diff --git a/src/plugins/cpptools/cppbaseprojectpartbuilder.cpp b/src/plugins/cpptools/cppbaseprojectpartbuilder.cpp new file mode 100644 index 00000000000..021b12b4c25 --- /dev/null +++ b/src/plugins/cpptools/cppbaseprojectpartbuilder.cpp @@ -0,0 +1,307 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "cppbaseprojectpartbuilder.h" + +#include "cppprojectfile.h" +#include "cppprojectfilecategorizer.h" +#include "projectinfo.h" + +#include +#include +#include + +#include + +namespace CppTools { + +BaseProjectPartBuilder::BaseProjectPartBuilder(ProjectInterface *project, + ProjectInfo &projectInfo) + : m_project(project) + , m_projectInfo(projectInfo) + , m_templatePart(new ProjectPart) +{ + QTC_CHECK(m_project); + m_templatePart->project = projectInfo.project(); + m_templatePart->displayName = m_project->displayName(); + m_templatePart->projectFile = m_project->projectFilePath(); +} + +void BaseProjectPartBuilder::setQtVersion(ProjectPart::QtVersion qtVersion) +{ + m_templatePart->qtVersion = qtVersion; +} + +void BaseProjectPartBuilder::setCFlags(const QStringList &flags) +{ + m_cFlags = flags; +} + +void BaseProjectPartBuilder::setCxxFlags(const QStringList &flags) +{ + m_cxxFlags = flags; +} + +void BaseProjectPartBuilder::setDefines(const QByteArray &defines) +{ + m_templatePart->projectDefines = defines; +} + +void BaseProjectPartBuilder::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths) +{ + m_templatePart->headerPaths = headerPaths; +} + +void BaseProjectPartBuilder::setIncludePaths(const QStringList &includePaths) +{ + m_templatePart->headerPaths.clear(); + + foreach (const QString &includeFile, includePaths) { + ProjectPartHeaderPath hp(includeFile, ProjectPartHeaderPath::IncludePath); + + // The simple project managers are utterly ignorant of frameworks on OSX, and won't report + // framework paths. The work-around is to check if the include path ends in ".framework", + // and if so, add the parent directory as framework path. + if (includeFile.endsWith(QLatin1String(".framework"))) { + const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/')); + if (slashIdx != -1) { + hp = ProjectPartHeaderPath(includeFile.left(slashIdx), + ProjectPartHeaderPath::FrameworkPath); + } + } + + m_templatePart->headerPaths += hp; + } +} + +void BaseProjectPartBuilder::setPreCompiledHeaders(const QStringList &preCompiledHeaders) +{ + m_templatePart->precompiledHeaders = preCompiledHeaders; +} + +void BaseProjectPartBuilder::setProjectFile(const QString &projectFile) +{ + m_templatePart->projectFile = projectFile; +} + +void BaseProjectPartBuilder::setDisplayName(const QString &displayName) +{ + m_templatePart->displayName = displayName; +} + +void BaseProjectPartBuilder::setConfigFileName(const QString &configFileName) +{ + m_templatePart->projectConfigFile = configFileName; +} + +QList BaseProjectPartBuilder::createProjectPartsForFiles(const QStringList &filePaths, + FileClassifier fileClassifier) +{ + QList languages; + + ProjectFileCategorizer cat(m_templatePart->displayName, filePaths, fileClassifier); + + if (cat.hasParts()) { + // The ProjextExplorer does not distinguish between other versions than C++ and QML. + languages += ProjectExplorer::Constants::LANG_CXX; + + if (cat.hasCSources()) { + createProjectPart(cat.cSources(), + cat.partName("C"), + ProjectPart::C11, + ProjectPart::NoExtensions); + } + + if (cat.hasObjcSources()) { + createProjectPart(cat.objcSources(), + cat.partName("Obj-C"), + ProjectPart::C11, + ProjectPart::ObjectiveCExtensions); + } + + if (cat.hasCxxSources()) { + createProjectPart(cat.cxxSources(), + cat.partName("C++"), + ProjectPart::CXX11, + ProjectPart::NoExtensions); + } + + if (cat.hasObjcxxSources()) { + createProjectPart(cat.objcxxSources(), + cat.partName("Obj-C++"), + ProjectPart::CXX11, + ProjectPart::ObjectiveCExtensions); + } + } + + return languages; +} + +namespace { + +class ToolChainEvaluator +{ +public: + ToolChainEvaluator(ProjectPart &projectPart, + const ToolChainInterface &toolChain) + : m_projectPart(projectPart) + , m_toolChain(toolChain) + , m_compilerFlags(toolChain.compilerFlags()) + { + } + + void evaluate() + { + mapLanguageVersion(); + mapLanguageExtensions(); + + addHeaderPaths(); + m_projectPart.toolchainDefines = m_toolChain.predefinedMacros(); + + m_projectPart.warningFlags = m_toolChain.warningFlags(); + m_projectPart.toolchainType = m_toolChain.type(); + m_projectPart.isMsvc2015Toolchain = m_toolChain.isMsvc2015Toolchain(); + m_projectPart.toolChainWordWidth = mapWordWith(m_toolChain.wordWidth()); + m_projectPart.targetTriple = m_toolChain.targetTriple(); + } + +private: + static ProjectPart::ToolChainWordWidth mapWordWith(unsigned wordWidth) + { + return wordWidth == 64 + ? ProjectPart::WordWidth64Bit + : ProjectPart::WordWidth32Bit; + } + + void mapLanguageVersion() + { + using namespace ProjectExplorer; + ProjectPart::LanguageVersion &languageVersion = m_projectPart.languageVersion; + + if (m_compilerFlags & ToolChain::StandardC11) + languageVersion = ProjectPart::C11; + else if (m_compilerFlags & ToolChain::StandardC99) + languageVersion = ProjectPart::C99; + else if (m_compilerFlags & ToolChain::StandardCxx17) + languageVersion = ProjectPart::CXX17; + else if (m_compilerFlags & ToolChain::StandardCxx14) + languageVersion = ProjectPart::CXX14; + else if (m_compilerFlags & ToolChain::StandardCxx11) + languageVersion = ProjectPart::CXX11; + else if (m_compilerFlags & ToolChain::StandardCxx98) + languageVersion = ProjectPart::CXX98; + } + + void mapLanguageExtensions() + { + using namespace ProjectExplorer; + ProjectPart::LanguageExtensions &languageExtensions = m_projectPart.languageExtensions; + + if (m_compilerFlags & ToolChain::BorlandExtensions) + languageExtensions |= ProjectPart::BorlandExtensions; + if (m_compilerFlags & ToolChain::GnuExtensions) + languageExtensions |= ProjectPart::GnuExtensions; + if (m_compilerFlags & ToolChain::MicrosoftExtensions) + languageExtensions |= ProjectPart::MicrosoftExtensions; + if (m_compilerFlags & ToolChain::OpenMP) + languageExtensions |= ProjectPart::OpenMPExtensions; + if (m_compilerFlags & ToolChain::ObjectiveC) + languageExtensions |= ProjectPart::ObjectiveCExtensions; + } + + static ProjectPartHeaderPath toProjectPartHeaderPath( + const ProjectExplorer::HeaderPath &headerPath) + { + const ProjectPartHeaderPath::Type headerPathType = + headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath + ? ProjectPartHeaderPath::FrameworkPath + : ProjectPartHeaderPath::IncludePath; + + return ProjectPartHeaderPath(headerPath.path(), headerPathType); + } + + void addHeaderPaths() + { + ProjectPartHeaderPaths &headerPaths = m_projectPart.headerPaths; + + foreach (const ProjectExplorer::HeaderPath &header, m_toolChain.systemHeaderPaths()) { + const ProjectPartHeaderPath headerPath = toProjectPartHeaderPath(header); + if (!headerPaths.contains(headerPath)) + headerPaths.push_back(headerPath); + } + } + +private: + ProjectPart &m_projectPart; + + const ToolChainInterface &m_toolChain; + const ProjectExplorer::ToolChain::CompilerFlags m_compilerFlags; +}; + +} // anynomous + +void BaseProjectPartBuilder::evaluateToolChain(ProjectPart &projectPart, + const ToolChainInterface &toolChain) +{ + ToolChainEvaluator evaluator(projectPart, toolChain); + evaluator.evaluate(); +} + +void BaseProjectPartBuilder::createProjectPart(const ProjectFiles &projectFiles, + const QString &partName, + ProjectPart::LanguageVersion languageVersion, + ProjectPart::LanguageExtensions languageExtensions) +{ + ProjectPart::Ptr part(m_templatePart->copy()); + part->displayName = partName; + part->files = projectFiles; + part->languageVersion = languageVersion; + QTC_ASSERT(part->project, return); + + // TODO: If not toolchain is set, show a warning + if (const ToolChainInterfacePtr toolChain = selectToolChain(languageVersion)) + evaluateToolChain(*part.data(), *toolChain.get()); + + part->languageExtensions |= languageExtensions; + part->updateLanguageFeatures(); + + m_projectInfo.appendProjectPart(part); +} + +ToolChainInterfacePtr BaseProjectPartBuilder::selectToolChain( + ProjectPart::LanguageVersion languageVersion) +{ + ToolChainInterfacePtr toolChain = nullptr; + + if (languageVersion < ProjectPart::CXX98) + toolChain = m_project->toolChain(ProjectExplorer::ToolChain::Language::C, m_cFlags); + + if (!toolChain) // Use Cxx toolchain for C projects without C compiler in kit and for C++ code + toolChain = m_project->toolChain(ProjectExplorer::ToolChain::Language::Cxx, m_cxxFlags); + + return toolChain; +} + +} // namespace CppTools diff --git a/src/plugins/cpptools/cppbaseprojectpartbuilder.h b/src/plugins/cpptools/cppbaseprojectpartbuilder.h new file mode 100644 index 00000000000..e4cea03e120 --- /dev/null +++ b/src/plugins/cpptools/cppbaseprojectpartbuilder.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "cpptools_global.h" + +#include "cppprojectinterface.h" +#include "projectpart.h" + +#include + +#include +#include + +namespace CppTools { + +class ProjectInfo; + +class CPPTOOLS_EXPORT BaseProjectPartBuilder +{ +public: + BaseProjectPartBuilder(ProjectInterface *project, ProjectInfo &projectInfo); + + void setDisplayName(const QString &displayName); + + void setProjectFile(const QString &projectFile); + void setConfigFileName(const QString &configFileName); + + void setQtVersion(ProjectPart::QtVersion qtVersion); + + void setCFlags(const QStringList &flags); + void setCxxFlags(const QStringList &flags); + + void setDefines(const QByteArray &defines); + void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths); + void setIncludePaths(const QStringList &includePaths); + + void setPreCompiledHeaders(const QStringList &preCompiledHeaders); + + using FileClassifier = std::function; + QList createProjectPartsForFiles(const QStringList &filePaths, + FileClassifier fileClassifier = FileClassifier()); + + static void evaluateToolChain(ProjectPart &projectPart, + const ToolChainInterface &selectToolChain); + +private: + void createProjectPart(const ProjectFiles &projectFiles, + const QString &partName, + ProjectPart::LanguageVersion languageVersion, + ProjectPart::LanguageExtensions languageExtensions); + ToolChainInterfacePtr selectToolChain(ProjectPart::LanguageVersion languageVersion); + +private: + std::unique_ptr m_project; + ProjectInfo &m_projectInfo; + + ProjectPart::Ptr m_templatePart; + QStringList m_cFlags; + QStringList m_cxxFlags; +}; + +} // namespace CppTools diff --git a/src/plugins/cpptools/cppprojectfile.cpp b/src/plugins/cpptools/cppprojectfile.cpp index a0666329be7..d1328b5bec4 100644 --- a/src/plugins/cpptools/cppprojectfile.cpp +++ b/src/plugins/cpptools/cppprojectfile.cpp @@ -39,6 +39,12 @@ ProjectFile::ProjectFile(const QString &filePath, Kind kind) { } +bool ProjectFile::operator==(const ProjectFile &other) const +{ + return path == other.path + && kind == other.kind; +} + ProjectFile::Kind ProjectFile::classify(const QString &filePath) { if (isAmbiguousHeader(filePath)) diff --git a/src/plugins/cpptools/cppprojectfile.h b/src/plugins/cpptools/cppprojectfile.h index e7e0ea82982..f6e2dde8cdc 100644 --- a/src/plugins/cpptools/cppprojectfile.h +++ b/src/plugins/cpptools/cppprojectfile.h @@ -59,6 +59,8 @@ public: ProjectFile() = default; ProjectFile(const QString &filePath, Kind kind); + bool operator==(const ProjectFile &other) const; + QString path; Kind kind = Unclassified; }; diff --git a/src/plugins/cpptools/cppprojectfilecategorizer.cpp b/src/plugins/cpptools/cppprojectfilecategorizer.cpp index 808448c1db6..bf0666e9afb 100644 --- a/src/plugins/cpptools/cppprojectfilecategorizer.cpp +++ b/src/plugins/cpptools/cppprojectfilecategorizer.cpp @@ -41,6 +41,7 @@ ProjectFileCategorizer::ProjectFileCategorizer(const QString &projectPartName, + (m_objcxxSources.isEmpty() ? 0 : 1); } +// TODO: Always tell the language version? QString ProjectFileCategorizer::partName(const QString &languageName) const { if (hasMultipleParts()) diff --git a/src/plugins/cpptools/cppprojectfilecategorizer.h b/src/plugins/cpptools/cppprojectfilecategorizer.h index 02620803223..a45c9bf99bc 100644 --- a/src/plugins/cpptools/cppprojectfilecategorizer.h +++ b/src/plugins/cpptools/cppprojectfilecategorizer.h @@ -54,7 +54,7 @@ public: ProjectFiles objcxxSources() const { return m_objcxxSources; } bool hasMultipleParts() const { return m_partCount > 1; } - bool hasNoParts() const { return m_partCount == 0; } + bool hasParts() const { return m_partCount > 0; } QString partName(const QString &languageName) const; diff --git a/src/plugins/cpptools/cppprojectinterface.h b/src/plugins/cpptools/cppprojectinterface.h new file mode 100644 index 00000000000..861f427882d --- /dev/null +++ b/src/plugins/cpptools/cppprojectinterface.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +namespace Core { +class Id; +} + +namespace ProjectExplorer { +class Project; +class ToolChain; +} + +namespace CppTools { + +class ToolChainInterface +{ +public: + virtual ~ToolChainInterface() {} + + virtual Core::Id type() const = 0; + virtual bool isMsvc2015Toolchain() const = 0; + + virtual unsigned wordWidth() const = 0; + virtual QString targetTriple() const = 0; + + virtual QByteArray predefinedMacros() const = 0; + virtual QList systemHeaderPaths() const = 0; + + virtual ProjectExplorer::WarningFlags warningFlags() const = 0; + virtual ProjectExplorer::ToolChain::CompilerFlags compilerFlags() const = 0; +}; + +using ToolChainInterfacePtr = std::unique_ptr; + +class ProjectInterface +{ +public: + virtual ~ProjectInterface() {} + + virtual QString displayName() const = 0; + virtual QString projectFilePath() const = 0; + + virtual ToolChainInterfacePtr toolChain(ProjectExplorer::ToolChain::Language language, + const QStringList &commandLineFlags) const = 0; +}; + +} // namespace CppTools diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 3795db2aca0..234dffbf2db 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -78,7 +78,9 @@ HEADERS += \ projectpartbuilder.h \ compileroptionsbuilder.h \ refactoringengineinterface.h \ - cppprojectfilecategorizer.h + cppprojectfilecategorizer.h \ + cppprojectinterface.h \ + cppbaseprojectpartbuilder.h \ SOURCES += \ abstracteditorsupport.cpp \ @@ -151,7 +153,8 @@ SOURCES += \ projectinfo.cpp \ projectpartbuilder.cpp \ compileroptionsbuilder.cpp \ - cppprojectfilecategorizer.cpp + cppprojectfilecategorizer.cpp \ + cppbaseprojectpartbuilder.cpp \ FORMS += \ clangdiagnosticconfigswidget.ui \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 565d43a1c31..0229c47a722 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -105,6 +105,8 @@ Project { "symbolsfindfilter.cpp", "symbolsfindfilter.h", "typehierarchybuilder.cpp", "typehierarchybuilder.h", "cppprojectfilecategorizer.cpp", "cppprojectfilecategorizer.h", + "cppprojectinterface.h", + "cppbaseprojectpartbuilder.cpp", "cppbaseprojectpartbuilder.h", ] Group { diff --git a/src/plugins/cpptools/cpptoolsunittestfiles.pri b/src/plugins/cpptools/cpptoolsunittestfiles.pri index a3ed69ef3fa..cb72833cad9 100644 --- a/src/plugins/cpptools/cpptoolsunittestfiles.pri +++ b/src/plugins/cpptools/cpptoolsunittestfiles.pri @@ -1,7 +1,11 @@ +# Currently there are no tests for the project explorer plugin, but we include +# headers from it that needs to have the export/import adapted for Windows. contains(CONFIG, dll) { DEFINES += CPPTOOLS_LIBRARY + DEFINES += PROJECTEXPLORER_LIBRARY } else { DEFINES += CPPTOOLS_STATIC_LIBRARY + DEFINES += PROJECTEXPLORER_STATIC_LIBRARY } HEADERS += \ @@ -9,11 +13,17 @@ HEADERS += \ $$PWD/senddocumenttracker.h \ $$PWD/projectpart.h \ $$PWD/compileroptionsbuilder.h \ - $$PWD/cppprojectfilecategorizer.h + $$PWD/cppprojectfilecategorizer.h \ + $$PWD/cppbaseprojectpartbuilder.h \ + $$PWD/projectinfo.h \ + $$PWD/cppprojectinterface.h \ + SOURCES += \ $$PWD/cppprojectfile.cpp \ $$PWD/senddocumenttracker.cpp \ $$PWD/projectpart.cpp \ $$PWD/compileroptionsbuilder.cpp \ - $$PWD/cppprojectfilecategorizer.cpp + $$PWD/cppprojectfilecategorizer.cpp \ + $$PWD/cppbaseprojectpartbuilder.cpp \ + $$PWD/projectinfo.cpp \ diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h index e278be769a1..6173cb9b691 100644 --- a/src/plugins/cpptools/projectpart.h +++ b/src/plugins/cpptools/projectpart.h @@ -58,7 +58,7 @@ public: // Types CXX03, CXX11, CXX14, - CXX17 + CXX17, }; enum LanguageExtension { diff --git a/src/plugins/cpptools/projectpartbuilder.cpp b/src/plugins/cpptools/projectpartbuilder.cpp index eaaa048b939..251d782d34f 100644 --- a/src/plugins/cpptools/projectpartbuilder.cpp +++ b/src/plugins/cpptools/projectpartbuilder.cpp @@ -25,279 +25,128 @@ #include "projectpartbuilder.h" -#include "cppprojectfile.h" -#include "cppprojectfilecategorizer.h" -#include "cpptoolsconstants.h" +#include "projectinfo.h" #include #include #include -#include #include -#include +#include #include -#include - -#include -#include namespace CppTools { -ProjectPartBuilder::ProjectPartBuilder(ProjectInfo &pInfo) - : m_templatePart(new ProjectPart) - , m_pInfo(pInfo) +class ToolChainImpl : public ToolChainInterface { - m_templatePart->project = pInfo.project(); - m_templatePart->displayName = pInfo.project()->displayName(); - m_templatePart->projectFile = pInfo.project()->projectFilePath().toString(); -} - -void ProjectPartBuilder::setQtVersion(ProjectPart::QtVersion qtVersion) -{ - m_templatePart->qtVersion = qtVersion; -} - -void ProjectPartBuilder::setCFlags(const QStringList &flags) -{ - m_cFlags = flags; -} - -void ProjectPartBuilder::setCxxFlags(const QStringList &flags) -{ - m_cxxFlags = flags; -} - -void ProjectPartBuilder::setDefines(const QByteArray &defines) -{ - m_templatePart->projectDefines = defines; -} - -void ProjectPartBuilder::setHeaderPaths(const ProjectPartHeaderPaths &headerPaths) -{ - m_templatePart->headerPaths = headerPaths; -} - -void ProjectPartBuilder::setIncludePaths(const QStringList &includePaths) -{ - m_templatePart->headerPaths.clear(); - - foreach (const QString &includeFile, includePaths) { - ProjectPartHeaderPath hp(includeFile, ProjectPartHeaderPath::IncludePath); - - // The simple project managers are utterly ignorant of frameworks on OSX, and won't report - // framework paths. The work-around is to check if the include path ends in ".framework", - // and if so, add the parent directory as framework path. - if (includeFile.endsWith(QLatin1String(".framework"))) { - const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/')); - if (slashIdx != -1) { - hp = ProjectPartHeaderPath(includeFile.left(slashIdx), - ProjectPartHeaderPath::FrameworkPath); - } - } - - m_templatePart->headerPaths += hp; - } -} - -void ProjectPartBuilder::setPreCompiledHeaders(const QStringList &pchs) -{ - m_templatePart->precompiledHeaders = pchs; -} - -void ProjectPartBuilder::setProjectFile(const QString &projectFile) -{ - m_templatePart->projectFile = projectFile; -} - -void ProjectPartBuilder::setDisplayName(const QString &displayName) -{ - m_templatePart->displayName = displayName; -} - -void ProjectPartBuilder::setConfigFileName(const QString &configFileName) -{ - m_templatePart->projectConfigFile = configFileName; -} - -QList ProjectPartBuilder::createProjectPartsForFiles(const QStringList &files, - FileClassifier fileClassifier) -{ - QSet languages; - - ProjectFileCategorizer cat(m_templatePart->displayName, files, fileClassifier); - if (cat.hasNoParts()) - return languages.toList(); - - using CppTools::ProjectFile; - using CppTools::ProjectPart; - - if (cat.hasCSources()) { - createProjectPart(cat.cSources(), - cat.partName(QCoreApplication::translate("CppTools", "C11")), - ProjectPart::C11, - ProjectPart::NoExtensions); - // TODO: there is no C... - languages += ProjectExplorer::Constants::LANG_CXX; - } - if (cat.hasObjcSources()) { - createProjectPart(cat.objcSources(), - cat.partName(QCoreApplication::translate("CppTools", "Obj-C11")), - ProjectPart::C11, - ProjectPart::ObjectiveCExtensions); - // TODO: there is no Ojective-C... - languages += ProjectExplorer::Constants::LANG_CXX; - } - if (cat.hasCxxSources()) { - createProjectPart(cat.cxxSources(), - cat.partName(QCoreApplication::translate("CppTools", "C++11")), - ProjectPart::CXX11, - ProjectPart::NoExtensions); - languages += ProjectExplorer::Constants::LANG_CXX; - } - if (cat.hasObjcxxSources()) { - createProjectPart(cat.objcxxSources(), - cat.partName(QCoreApplication::translate("CppTools", "Obj-C++11")), - ProjectPart::CXX11, - ProjectPart::ObjectiveCExtensions); - // TODO: there is no Objective-C++... - languages += ProjectExplorer::Constants::LANG_CXX; +public: + ToolChainImpl(ProjectExplorer::ToolChain &toolChain, + const ProjectExplorer::Kit *kit, + const QStringList &commandLineFlags) + : m_toolChain(toolChain) + , m_kit(kit) + , m_commandLineFlags(commandLineFlags) + { } - return languages.toList(); -} - -namespace { - -ProjectPartHeaderPath toProjectPartHeaderPath(const ProjectExplorer::HeaderPath &headerPath) -{ - const ProjectPartHeaderPath::Type headerPathType = - headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath - ? ProjectPartHeaderPath::FrameworkPath - : ProjectPartHeaderPath::IncludePath; - - return ProjectPartHeaderPath(headerPath.path(), headerPathType); -} - -QString targetTriple(ProjectExplorer::Project *project, const Core::Id &toolchainId) -{ - using namespace ProjectExplorer; - - if (toolchainId == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) - return QLatin1String("i686-pc-windows-msvc"); - - if (project) { - if (Target *target = project->activeTarget()) { - if (ToolChain *toolChain = ToolChainKitInformation::toolChain(target->kit(), ToolChain::Language::Cxx)) - return toolChain->originalTargetTriple(); - } + Core::Id type() const override + { + return m_toolChain.typeId(); } - return QString(); -} - -} - -/*! - \brief Retrieves info from concrete compiler using it's flags. - - \param projectPart Project part which can never be an null pointer. - \param toolChain Either nullptr or toolchain for project's active target. - \param cxxflags C++ or Objective-C++ flags. - \param cflags C or ObjectiveC flags if possible, \a cxxflags otherwise. -*/ -void ProjectPartBuilder::evaluateProjectPartToolchain( - ProjectPart *projectPart, - const ProjectExplorer::ToolChain *toolChain, - const QStringList &commandLineFlags, - const Utils::FileName &sysRoot) -{ - if (toolChain == nullptr) - return; - - using namespace ProjectExplorer; - ToolChain::CompilerFlags flags = toolChain->compilerFlags(commandLineFlags); - auto &languageVersion = projectPart->languageVersion; - - if (flags & ToolChain::StandardC11) - languageVersion = ProjectPart::C11; - else if (flags & ToolChain::StandardC99) - languageVersion = ProjectPart::C99; - else if (flags & ToolChain::StandardCxx17) - languageVersion = ProjectPart::CXX17; - else if (flags & ToolChain::StandardCxx14) - languageVersion = ProjectPart::CXX14; - else if (flags & ToolChain::StandardCxx11) - languageVersion = ProjectPart::CXX11; - else if (flags & ToolChain::StandardCxx98) - languageVersion = ProjectPart::CXX98; - - auto &languageExtensions = projectPart->languageExtensions; - - if (flags & ToolChain::BorlandExtensions) - languageExtensions |= ProjectPart::BorlandExtensions; - if (flags & ToolChain::GnuExtensions) - languageExtensions |= ProjectPart::GnuExtensions; - if (flags & ToolChain::MicrosoftExtensions) - languageExtensions |= ProjectPart::MicrosoftExtensions; - if (flags & ToolChain::OpenMP) - languageExtensions |= ProjectPart::OpenMPExtensions; - if (flags & ToolChain::ObjectiveC) - languageExtensions |= ProjectPart::ObjectiveCExtensions; - - projectPart->warningFlags = toolChain->warningFlags(commandLineFlags); - - const QList headers = toolChain->systemHeaderPaths(commandLineFlags, sysRoot); - foreach (const ProjectExplorer::HeaderPath &header, headers) { - const ProjectPartHeaderPath headerPath = toProjectPartHeaderPath(header); - if (!projectPart->headerPaths.contains(headerPath)) - projectPart->headerPaths.push_back(headerPath); + bool isMsvc2015Toolchain() const override + { + return m_toolChain.targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor; } - projectPart->toolchainDefines = toolChain->predefinedMacros(commandLineFlags); - projectPart->toolchainType = toolChain->typeId(); - projectPart->isMsvc2015Toolchain - = toolChain->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor; - projectPart->toolChainWordWidth = toolChain->targetAbi().wordWidth() == 64 - ? ProjectPart::WordWidth64Bit - : ProjectPart::WordWidth32Bit; - projectPart->targetTriple = targetTriple(projectPart->project, toolChain->typeId()); - projectPart->updateLanguageFeatures(); -} - -void ProjectPartBuilder::createProjectPart(const QVector &theSources, - const QString &partName, - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions) -{ - ProjectPart::Ptr part(m_templatePart->copy()); - part->displayName = partName; - part->files = theSources; - part->languageVersion = languageVersion; - - QTC_ASSERT(part->project, return); - if (ProjectExplorer::Target *activeTarget = part->project->activeTarget()) { - if (ProjectExplorer::Kit *kit = activeTarget->kit()) { - ProjectExplorer::ToolChain *toolChain = nullptr; - if (languageVersion < ProjectPart::CXX98) - toolChain = ProjectExplorer::ToolChainKitInformation::toolChain(kit, ProjectExplorer::ToolChain::Language::C); - if (!toolChain) // Use Cxx toolchain for C projects without C compiler in kit and for C++ code - toolChain = ProjectExplorer::ToolChainKitInformation::toolChain(kit, ProjectExplorer::ToolChain::Language::Cxx); - - if (toolChain) { - const QStringList flags - = (toolChain->language() == ProjectExplorer::ToolChain::Language::Cxx) - ? m_cxxFlags : m_cFlags; - evaluateProjectPartToolchain(part.data(), - toolChain, - flags, - ProjectExplorer::SysRootKitInformation::sysRoot(kit)); - } - } + unsigned wordWidth() const override + { + return m_toolChain.targetAbi().wordWidth(); } - part->languageExtensions |= languageExtensions; + QString targetTriple() const override + { + if (type() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) + return QLatin1String("i686-pc-windows-msvc"); - m_pInfo.appendProjectPart(part); + return m_toolChain.originalTargetTriple(); + } + + QByteArray predefinedMacros() const override + { + return m_toolChain.predefinedMacros(m_commandLineFlags); + } + + QList systemHeaderPaths() const override + { + return m_toolChain.systemHeaderPaths( + m_commandLineFlags, + ProjectExplorer::SysRootKitInformation::sysRoot(m_kit)); + } + + ProjectExplorer::WarningFlags warningFlags() const override + { + return m_toolChain.warningFlags(m_commandLineFlags); + } + + ProjectExplorer::ToolChain::CompilerFlags compilerFlags() const override + { + return m_toolChain.compilerFlags(m_commandLineFlags); + } + +private: + ProjectExplorer::ToolChain &m_toolChain; + const ProjectExplorer::Kit *m_kit = nullptr; + const QStringList m_commandLineFlags; +}; + +class ProjectImpl : public ProjectInterface +{ +public: + ProjectImpl(ProjectExplorer::Project &project) + : m_project(project) + { + if (ProjectExplorer::Target *activeTarget = m_project.activeTarget()) + m_kit = activeTarget->kit(); + } + + QString displayName() const override + { + return m_project.displayName(); + } + + QString projectFilePath() const override + { + return m_project.projectFilePath().toString(); + } + + ToolChainInterfacePtr toolChain(ProjectExplorer::ToolChain::Language language, + const QStringList &commandLineFlags) const override + { + using namespace ProjectExplorer; + + if (ProjectExplorer::ToolChain *t = ToolChainKitInformation::toolChain(m_kit, language)) + return ToolChainInterfacePtr(new ToolChainImpl(*t, m_kit, commandLineFlags)); + + return ToolChainInterfacePtr(); + } + +private: + ProjectExplorer::Project &m_project; + ProjectExplorer::Kit *m_kit = nullptr; +}; + +ProjectPartBuilder::ProjectPartBuilder(ProjectInfo &projectInfo) + : BaseProjectPartBuilder(new ProjectImpl(*projectInfo.project().data()), projectInfo) +{ +} + +void ProjectPartBuilder::evaluateToolChain(ProjectPart &projectPart, + ProjectExplorer::ToolChain &toolChain, + const ProjectExplorer::Kit *kit, + const QStringList commandLineFlags) +{ + const ToolChainImpl toolChainImpl(toolChain, kit, commandLineFlags); + BaseProjectPartBuilder::evaluateToolChain(projectPart, toolChainImpl); } } // namespace CppTools diff --git a/src/plugins/cpptools/projectpartbuilder.h b/src/plugins/cpptools/projectpartbuilder.h index 91eaca910fe..3318b803041 100644 --- a/src/plugins/cpptools/projectpartbuilder.h +++ b/src/plugins/cpptools/projectpartbuilder.h @@ -27,53 +27,26 @@ #include "cpptools_global.h" -#include "projectinfo.h" -#include "projectpart.h" - -#include +#include "cppbaseprojectpartbuilder.h" namespace ProjectExplorer { +class Kit; class ToolChain; } namespace CppTools { -class CPPTOOLS_EXPORT ProjectPartBuilder +class ProjectInfo; + +class CPPTOOLS_EXPORT ProjectPartBuilder : public BaseProjectPartBuilder { public: - ProjectPartBuilder(ProjectInfo &m_pInfo); + ProjectPartBuilder(ProjectInfo &projectInfo); - void setQtVersion(ProjectPart::QtVersion qtVersion); - void setCFlags(const QStringList &flags); - void setCxxFlags(const QStringList &flags); - void setDefines(const QByteArray &defines); - void setHeaderPaths(const ProjectPartHeaderPaths &headerPaths); - void setIncludePaths(const QStringList &includePaths); - void setPreCompiledHeaders(const QStringList &pchs); - void setProjectFile(const QString &projectFile); - void setDisplayName(const QString &displayName); - void setConfigFileName(const QString &configFileName); - - using FileClassifier = std::function; - - QList createProjectPartsForFiles(const QStringList &files, - FileClassifier fileClassifier = FileClassifier()); - - static void evaluateProjectPartToolchain(ProjectPart *projectPart, - const ProjectExplorer::ToolChain *toolChain, - const QStringList &commandLineFlags, - const Utils::FileName &sysRoot); - -private: - void createProjectPart(const QVector &theSources, - const QString &partName, - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions); - -private: - ProjectPart::Ptr m_templatePart; - ProjectInfo &m_pInfo; - QStringList m_cFlags, m_cxxFlags; + static void evaluateToolChain(ProjectPart &projectPart, + ProjectExplorer::ToolChain &toolChain, + const ProjectExplorer::Kit *kit, + const QStringList commandLineFlags); }; } // namespace CppTools diff --git a/src/plugins/projectexplorer/projectexplorer_export.h b/src/plugins/projectexplorer/projectexplorer_export.h index 31493696f1c..cab996e4aa5 100644 --- a/src/plugins/projectexplorer/projectexplorer_export.h +++ b/src/plugins/projectexplorer/projectexplorer_export.h @@ -29,6 +29,8 @@ #if defined(PROJECTEXPLORER_LIBRARY) # define PROJECTEXPLORER_EXPORT Q_DECL_EXPORT +#elif defined(PROJECTEXPLORER_STATIC_LIBRARY) +# define PROJECTEXPLORER_EXPORT #else # define PROJECTEXPLORER_EXPORT Q_DECL_IMPORT #endif diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 6d87406d9c0..737628c56be 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -413,9 +413,8 @@ void QmakeProject::updateCppCodeModel() // TODO: there is no LANG_OBJCXX, so: const QStringList cxxflags = pro->variableValue(CppFlagsVar); - CppTools::ProjectPartBuilder::evaluateProjectPartToolchain( - templatePart.data(), ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx), - cxxflags, SysRootKitInformation::sysRoot(k)); + if (ToolChain *t = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx)) + CppTools::ProjectPartBuilder::evaluateToolChain(*templatePart.data(), *t, k, cxxflags); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, true); ProjectPart::Ptr cppPart = templatePart->copy(); diff --git a/tests/unit/unittest/cppbaseprojectpartbuilder-test.cpp b/tests/unit/unittest/cppbaseprojectpartbuilder-test.cpp new file mode 100644 index 00000000000..05c33fb5a3d --- /dev/null +++ b/tests/unit/unittest/cppbaseprojectpartbuilder-test.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" +#include "gtest-qt-printing.h" +#include "mimedatabase-utilities.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +using CppTools::BaseProjectPartBuilder; +using CppTools::ProjectFile; +using CppTools::ProjectFiles; +using CppTools::ProjectInfo; +using CppTools::ProjectInterface; +using CppTools::ProjectPart; +using CppTools::ToolChainInterface; +using CppTools::ToolChainInterfacePtr; + +using testing::Eq; + +namespace { + +class EditableToolChain : public CppTools::ToolChainInterface +{ +public: + void setCompilerFlags(ProjectExplorer::ToolChain::CompilerFlags compilerFlags) + { + m_compilerFlags = compilerFlags; + } + +private: + Core::Id type() const override { return Core::Id(); } + bool isMsvc2015Toolchain() const override { return false; } + unsigned wordWidth() const override { return 64; } + QString targetTriple() const override { return QString(); } + + QByteArray predefinedMacros() const override { return QByteArray(); } + QList systemHeaderPaths() const override + { return QList(); } + + ProjectExplorer::WarningFlags warningFlags() const override + { return ProjectExplorer::WarningFlags(); } + + ProjectExplorer::ToolChain::CompilerFlags compilerFlags() const override + { return m_compilerFlags; } + +private: + ProjectExplorer::ToolChain::CompilerFlags m_compilerFlags; +}; + +class EditableProject : public CppTools::ProjectInterface +{ +public: + void setToolChain(ToolChainInterface *toolChain) + { + m_toolChain = toolChain; + } + +private: + QString displayName() const override { return QString(); } + QString projectFilePath() const override { return QString(); } + + ToolChainInterfacePtr toolChain(ProjectExplorer::ToolChain::Language, + const QStringList &) const override + { return ToolChainInterfacePtr(m_toolChain); } + +private: + CppTools::ToolChainInterface *m_toolChain = nullptr; +}; + +class BaseProjectPartBuilder : public ::testing::Test +{ +protected: + void SetUp() override; + + QObject dummyProjectExplorerProject; + ProjectInfo projectInfo{static_cast(&dummyProjectExplorerProject)}; +}; + +TEST_F(BaseProjectPartBuilder, CreateNoPartsForEmptyFileList) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList()); + + ASSERT_TRUE(projectInfo.projectParts().isEmpty()); +} + +TEST_F(BaseProjectPartBuilder, CreateSinglePart) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.cpp" << "foo.h"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); +} + +TEST_F(BaseProjectPartBuilder, CreateMultipleParts) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.cpp" << "foo.h" + << "bar.c" << "bar.h"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(2)); +} + +TEST_F(BaseProjectPartBuilder, ProjectPartIndicatesObjectiveCExtensionsByDefault) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.mm"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); + const ProjectPart &projectPart = *projectInfo.projectParts().at(0); + ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions); +} + +TEST_F(BaseProjectPartBuilder, ProjectPartHasLatestLanguageVersionByDefault) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.cpp"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); + const ProjectPart &projectPart = *projectInfo.projectParts().at(0); + ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX11)); +} + +TEST_F(BaseProjectPartBuilder, ToolChainSetsLanguageVersion) +{ + auto toolChain = new EditableToolChain; + toolChain->setCompilerFlags(ProjectExplorer::ToolChain::StandardCxx98); + auto project = new EditableProject; + project->setToolChain(toolChain); + ::BaseProjectPartBuilder builder(project, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.cpp"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); + const ProjectPart &projectPart = *projectInfo.projectParts().at(0); + ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX98)); +} + +TEST_F(BaseProjectPartBuilder, ToolChainSetsLanguageExtensions) +{ + auto toolChain = new EditableToolChain; + toolChain->setCompilerFlags(ProjectExplorer::ToolChain::MicrosoftExtensions); + auto project = new EditableProject; + project->setToolChain(toolChain); + ::BaseProjectPartBuilder builder(project, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.cpp"); + + ASSERT_THAT(projectInfo.projectParts().size(), Eq(1)); + const ProjectPart &projectPart = *projectInfo.projectParts().at(0); + ASSERT_TRUE(projectPart.languageExtensions & ProjectPart::MicrosoftExtensions); +} + +TEST_F(BaseProjectPartBuilder, ProjectFileKindsMatchProjectPartVersion) +{ + ::BaseProjectPartBuilder builder(new EditableProject, projectInfo); + + builder.createProjectPartsForFiles(QStringList() << "foo.h"); + + const QList projectParts = projectInfo.projectParts(); + ASSERT_THAT(projectParts.size(), Eq(4)); + ASSERT_THAT(projectParts.at(0)->languageVersion, Eq(ProjectPart::C11)); + ASSERT_THAT(projectParts.at(0)->files.at(0).kind, Eq(ProjectFile::CHeader)); + ASSERT_THAT(projectParts.at(1)->languageVersion, Eq(ProjectPart::C11)); + ASSERT_THAT(projectParts.at(1)->files.at(0).kind, Eq(ProjectFile::ObjCHeader)); + ASSERT_THAT(projectParts.at(2)->languageVersion, Eq(ProjectPart::CXX11)); + ASSERT_THAT(projectParts.at(2)->files.at(0).kind, Eq(ProjectFile::CXXHeader)); + ASSERT_THAT(projectParts.at(3)->languageVersion, Eq(ProjectPart::CXX11)); + ASSERT_THAT(projectParts.at(3)->files.at(0).kind, Eq(ProjectFile::ObjCXXHeader)); +} + +void BaseProjectPartBuilder::SetUp() +{ + ASSERT_TRUE(MimeDataBaseUtilities::addCppToolsMimeTypes()); +} + +} // anonymous namespace diff --git a/tests/unit/unittest/cppprojectfilecategorizer-test.cpp b/tests/unit/unittest/cppprojectfilecategorizer-test.cpp index 5fac453809b..33866db6a2e 100644 --- a/tests/unit/unittest/cppprojectfilecategorizer-test.cpp +++ b/tests/unit/unittest/cppprojectfilecategorizer-test.cpp @@ -25,6 +25,7 @@ #include "googletest.h" #include "gtest-qt-printing.h" +#include "mimedatabase-utilities.h" #include #include @@ -46,12 +47,6 @@ using testing::AllOf; namespace CppTools { -bool operator==(const ProjectFile &lhs, const ProjectFile &rhs) -{ - return lhs.path == rhs.path - && lhs.kind == rhs.kind; -} - void PrintTo(const ProjectFile &projectFile, std::ostream *os) { *os << "ProjectFile("; @@ -71,7 +66,6 @@ protected: void SetUp() override; static ProjectFiles singleFile(const QString &filePath, ProjectFile::Kind kind); - static void initMimeDataBaseIfNotYetDone(); protected: const QString dummyProjectPartName; @@ -192,7 +186,7 @@ TEST_F(ProjectFileCategorizer, AmbiguousHeaderOnly) void ProjectFileCategorizer::SetUp() { - initMimeDataBaseIfNotYetDone(); + ASSERT_TRUE(MimeDataBaseUtilities::addCppToolsMimeTypes()); } QVectorProjectFileCategorizer::singleFile(const QString &filePath, @@ -201,16 +195,4 @@ QVectorProjectFileCategorizer::singleFile(const QString & return { ProjectFile(filePath, kind) }; } -void ProjectFileCategorizer::initMimeDataBaseIfNotYetDone() -{ - static bool isInitialized = false; - if (isInitialized) - return; - - const QString filePath = TESTDATA_DIR "/../../../../src/plugins/cpptools/CppTools.mimetypes.xml"; - ASSERT_TRUE(QFileInfo::exists(filePath)); - Utils::MimeDatabase::addMimeTypes(filePath); - isInitialized = true; -} - } // anonymous namespace diff --git a/tests/unit/unittest/mimedatabase-utilities.cpp b/tests/unit/unittest/mimedatabase-utilities.cpp new file mode 100644 index 00000000000..ecc54354c7e --- /dev/null +++ b/tests/unit/unittest/mimedatabase-utilities.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "mimedatabase-utilities.h" + +#include +#include + +#include + +namespace MimeDataBaseUtilities +{ + +bool addCppToolsMimeTypes() +{ + static bool alreadyAdded = false; + if (alreadyAdded) + return true; + + const QString filePath + = TESTDATA_DIR "/../../../../src/plugins/cpptools/CppTools.mimetypes.xml"; + if (QFileInfo::exists(filePath)) { + Utils::MimeDatabase::addMimeTypes(filePath); + alreadyAdded = true; + return true; + } + + return false; +} + +} diff --git a/tests/unit/unittest/mimedatabase-utilities.h b/tests/unit/unittest/mimedatabase-utilities.h new file mode 100644 index 00000000000..89f9ee28ae3 --- /dev/null +++ b/tests/unit/unittest/mimedatabase-utilities.h @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace MimeDataBaseUtilities +{ + bool addCppToolsMimeTypes(); +} diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 6101590a836..48131fe2ac5 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -29,7 +29,9 @@ SOURCES += \ clientserveroutsideprocess.cpp \ lineprefixer-test.cpp \ cppprojectfilecategorizer-test.cpp \ + cppbaseprojectpartbuilder-test.cpp \ processevents-utilities.cpp \ + mimedatabase-utilities.cpp \ readandwritemessageblock-test.cpp \ sizedarray-test.cpp \ smallstring-test.cpp \ @@ -119,6 +121,7 @@ HEADERS += \ googletest.h \ gtest-qt-printing.h \ processevents-utilities.h \ + mimedatabase-utilities.h \ spydummy.h \ sourcerangecontainer-matcher.h \ dynamicastmatcherdiagnosticcontainer-matcher.h \