1 /*
2     SPDX-FileCopyrightText: 2015 Sergey Kalinichev <kalinichev.so.0@gmail.com>
3 
4     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6 
7 #include "clangsettingsmanager.h"
8 
9 #include <KConfigGroup>
10 #include <KConfig>
11 
12 #include <interfaces/icore.h>
13 #include <interfaces/isession.h>
14 #include <interfaces/iproject.h>
15 #include <custom-definesandincludes/idefinesandincludesmanager.h>
16 #include <util/path.h>
17 
18 #include <project/projectmodel.h>
19 
20 using namespace KDevelop;
21 
22 namespace
23 {
24     const QString settingsGroup = QStringLiteral("Clang Settings");
25 
26     const QString macros = QStringLiteral("macros");
27     const QString lookAhead = QStringLiteral("lookAhead");
28 
29     const QString forwardDeclare = QStringLiteral("forwardDeclare");
30 
readAssistantsSettings(KConfig * cfg)31 AssistantsSettings readAssistantsSettings(KConfig* cfg)
32 {
33     auto grp = cfg->group(settingsGroup);
34     AssistantsSettings settings;
35 
36     settings.forwardDeclare = grp.readEntry(forwardDeclare, true);
37 
38     return settings;
39 }
40 
readCodeCompletionSettings(KConfig * cfg)41 CodeCompletionSettings readCodeCompletionSettings(KConfig* cfg)
42 {
43     auto grp = cfg->group(settingsGroup);
44     CodeCompletionSettings settings;
45 
46     settings.macros = grp.readEntry(macros, true);
47     settings.lookAhead = grp.readEntry(lookAhead, false);
48 
49     return settings;
50 }
51 }
52 
self()53 ClangSettingsManager* ClangSettingsManager::self()
54 {
55     static ClangSettingsManager manager;
56     return &manager;
57 }
58 
assistantsSettings() const59 AssistantsSettings ClangSettingsManager::assistantsSettings() const
60 {
61     auto cfg = ICore::self()->activeSession()->config();
62     return readAssistantsSettings(cfg.data());
63 }
64 
codeCompletionSettings() const65 CodeCompletionSettings ClangSettingsManager::codeCompletionSettings() const
66 {
67     if (m_enableTesting) {
68         CodeCompletionSettings settings;
69         settings.lookAhead = true;
70         settings.macros = true;
71         return settings;
72     }
73 
74     auto cfg = ICore::self()->activeSession()->config();
75     return readCodeCompletionSettings(cfg.data());
76 }
77 
parserSettings(KDevelop::ProjectBaseItem * item) const78 ParserSettings ClangSettingsManager::parserSettings(KDevelop::ProjectBaseItem* item) const
79 {
80     return {IDefinesAndIncludesManager::manager()->parserArguments(item)};
81 }
82 
parserSettings(const QString & path) const83 ParserSettings ClangSettingsManager::parserSettings(const QString& path) const
84 {
85     return {IDefinesAndIncludesManager::manager()->parserArguments(path)};
86 }
87 
ClangSettingsManager()88 ClangSettingsManager::ClangSettingsManager()
89 {}
90 
isCpp() const91 bool ParserSettings::isCpp() const
92 {
93     return parserOptions.contains(QLatin1String("-std=c++")) || parserOptions.contains(QLatin1String("-std=gnu++"));
94 }
95 
toClangAPI() const96 QVector<QByteArray> ParserSettings::toClangAPI() const
97 {
98     // TODO: This is not efficient.
99 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
100     const auto list = parserOptions.splitRef(QLatin1Char(' '), Qt::SkipEmptyParts);
101 #else
102     auto list = parserOptions.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
103 #endif
104     QVector<QByteArray> result;
105     result.reserve(list.size());
106 
107     std::transform(list.constBegin(), list.constEnd(),
108                    std::back_inserter(result),
109                    [] (const QStringRef &argument) { return argument.toUtf8(); });
110 
111     return result;
112 }
113 
operator ==(const ParserSettings & rhs) const114 bool ParserSettings::operator==(const ParserSettings& rhs) const
115 {
116     return parserOptions == rhs.parserOptions;
117 }
118