Changeset View
Changeset View
Standalone View
Standalone View
projectmanagers/cmake/cmakeimportjsonjob.cpp
Show All 36 Lines | |||||
37 | #include <QtConcurrentRun> | 37 | #include <QtConcurrentRun> | ||
38 | #include <QFutureWatcher> | 38 | #include <QFutureWatcher> | ||
39 | #include <QRegularExpression> | 39 | #include <QRegularExpression> | ||
40 | 40 | | |||
41 | using namespace KDevelop; | 41 | using namespace KDevelop; | ||
42 | 42 | | |||
43 | namespace { | 43 | namespace { | ||
44 | 44 | | |||
45 | CMakeJsonData importCommands(const Path& commandsFile) | 45 | CMakeFilesCompilationData importCommands(const Path& commandsFile) | ||
46 | { | 46 | { | ||
47 | // NOTE: to get compile_commands.json, you need -DCMAKE_EXPORT_COMPILE_COMMANDS=ON | 47 | // NOTE: to get compile_commands.json, you need -DCMAKE_EXPORT_COMPILE_COMMANDS=ON | ||
48 | QFile f(commandsFile.toLocalFile()); | 48 | QFile f(commandsFile.toLocalFile()); | ||
49 | bool r = f.open(QFile::ReadOnly|QFile::Text); | 49 | bool r = f.open(QFile::ReadOnly|QFile::Text); | ||
50 | if(!r) { | 50 | if(!r) { | ||
51 | qCWarning(CMAKE) << "Couldn't open commands file" << commandsFile; | 51 | qCWarning(CMAKE) << "Couldn't open commands file" << commandsFile; | ||
52 | return {}; | 52 | return {}; | ||
53 | } | 53 | } | ||
54 | 54 | | |||
55 | qCDebug(CMAKE) << "Found commands file" << commandsFile; | 55 | qCDebug(CMAKE) << "Found commands file" << commandsFile; | ||
56 | 56 | | |||
57 | CMakeJsonData data; | 57 | CMakeFilesCompilationData data; | ||
58 | QJsonParseError error; | 58 | QJsonParseError error; | ||
59 | const QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error); | 59 | const QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error); | ||
60 | if (error.error) { | 60 | if (error.error) { | ||
61 | qCWarning(CMAKE) << "Failed to parse JSON in commands file:" << error.errorString() << commandsFile; | 61 | qCWarning(CMAKE) << "Failed to parse JSON in commands file:" << error.errorString() << commandsFile; | ||
62 | data.isValid = false; | 62 | data.isValid = false; | ||
63 | return data; | 63 | return data; | ||
64 | } else if (!document.isArray()) { | 64 | } else if (!document.isArray()) { | ||
65 | qCWarning(CMAKE) << "JSON document in commands file is not an array: " << commandsFile; | 65 | qCWarning(CMAKE) << "JSON document in commands file is not an array: " << commandsFile; | ||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Line(s) | 135 | return ImportData { | |||
136 | importCommands(commandsFile), | 136 | importCommands(commandsFile), | ||
137 | CMake::enumerateTargets(targetsFilePath, sourceDir, buildPath), | 137 | CMake::enumerateTargets(targetsFilePath, sourceDir, buildPath), | ||
138 | importTestSuites(buildPath) | 138 | importTestSuites(buildPath) | ||
139 | }; | 139 | }; | ||
140 | } | 140 | } | ||
141 | 141 | | |||
142 | } | 142 | } | ||
143 | 143 | | |||
144 | CMakeImportJob::CMakeImportJob(IProject* project, QObject* parent) | 144 | CMakeImportJsonJob::CMakeImportJsonJob(IProject* project, QObject* parent) | ||
145 | : KJob(parent) | 145 | : KJob(parent) | ||
146 | , m_project(project) | 146 | , m_project(project) | ||
147 | , m_data({}) | ||||
147 | { | 148 | { | ||
148 | connect(&m_futureWatcher, &QFutureWatcher<ImportData>::finished, this, &CMakeImportJob::importFinished); | 149 | connect(&m_futureWatcher, &QFutureWatcher<ImportData>::finished, this, &CMakeImportJsonJob::importCompileCommandsJsonFinished); | ||
149 | } | 150 | } | ||
150 | 151 | | |||
151 | CMakeImportJob::~CMakeImportJob() | 152 | CMakeImportJsonJob::~CMakeImportJsonJob() | ||
152 | { | 153 | {} | ||
153 | } | | |||
154 | 154 | | |||
155 | void CMakeImportJob::start() | 155 | void CMakeImportJsonJob::start() | ||
156 | { | 156 | { | ||
157 | auto commandsFile = CMake::commandsFile(project()); | 157 | auto commandsFile = CMake::commandsFile(project()); | ||
158 | if (!QFileInfo::exists(commandsFile.toLocalFile())) { | 158 | if (!QFileInfo::exists(commandsFile.toLocalFile())) { | ||
159 | qCWarning(CMAKE) << "Could not import CMake project" << project()->path() << "('compile_commands.json' missing)"; | 159 | qCWarning(CMAKE) << "Could not import CMake project" << project()->path() << "('compile_commands.json' missing)"; | ||
160 | emitResult(); | 160 | emitResult(); | ||
161 | return; | 161 | return; | ||
162 | } | 162 | } | ||
163 | 163 | | |||
164 | const Path currentBuildDir = CMake::currentBuildDir(m_project); | 164 | const Path currentBuildDir = CMake::currentBuildDir(m_project); | ||
165 | Q_ASSERT (!currentBuildDir.isEmpty()); | 165 | Q_ASSERT (!currentBuildDir.isEmpty()); | ||
166 | 166 | | |||
167 | const Path targetsFilePath = CMake::targetDirectoriesFile(m_project); | 167 | const Path targetsFilePath = CMake::targetDirectoriesFile(m_project); | ||
168 | const QString sourceDir = m_project->path().toLocalFile(); | 168 | const QString sourceDir = m_project->path().toLocalFile(); | ||
169 | 169 | | |||
170 | auto future = QtConcurrent::run(import, commandsFile, targetsFilePath, sourceDir, currentBuildDir); | 170 | auto future = QtConcurrent::run(import, commandsFile, targetsFilePath, sourceDir, currentBuildDir); | ||
171 | m_futureWatcher.setFuture(future); | 171 | m_futureWatcher.setFuture(future); | ||
172 | } | 172 | } | ||
173 | 173 | | |||
174 | void CMakeImportJob::importFinished() | 174 | void CMakeImportJsonJob::importCompileCommandsJsonFinished() | ||
175 | { | 175 | { | ||
176 | Q_ASSERT(m_project->thread() == QThread::currentThread()); | 176 | Q_ASSERT(m_project->thread() == QThread::currentThread()); | ||
177 | Q_ASSERT(m_futureWatcher.isFinished()); | 177 | Q_ASSERT(m_futureWatcher.isFinished()); | ||
178 | 178 | | |||
179 | auto future = m_futureWatcher.future(); | 179 | auto future = m_futureWatcher.future(); | ||
180 | auto data = future.result(); | 180 | auto data = future.result(); | ||
181 | if (!data.json.isValid) { | 181 | if (!data.compilationData.isValid) { | ||
182 | qCWarning(CMAKE) << "Could not import CMake project ('compile_commands.json' invalid)"; | 182 | qCWarning(CMAKE) << "Could not import CMake project ('compile_commands.json' invalid)"; | ||
183 | emitResult(); | 183 | emitResult(); | ||
184 | return; | 184 | return; | ||
185 | } | 185 | } | ||
186 | 186 | | |||
187 | m_data = data.json; | 187 | m_data = CMakeProjectData {data.targets, data.compilationData, data.testSuites}; | ||
188 | m_targets = data.targets; | 188 | qCDebug(CMAKE) << "Done importing, found" << data.compilationData.files.count() << "entries for" << project()->path(); | ||
189 | m_testSuites = data.testSuites; | | |||
190 | qCDebug(CMAKE) << "Done importing, found" << m_data.files.count() << "entries for" << project()->path(); | | |||
191 | 189 | | |||
192 | emitResult(); | 190 | emitResult(); | ||
193 | } | 191 | } | ||
194 | 192 | | |||
195 | IProject* CMakeImportJob::project() const | 193 | IProject* CMakeImportJsonJob::project() const | ||
196 | { | 194 | { | ||
197 | return m_project; | 195 | return m_project; | ||
198 | } | 196 | } | ||
199 | 197 | | |||
200 | CMakeJsonData CMakeImportJob::jsonData() const | 198 | CMakeProjectData CMakeImportJsonJob::projectData() const | ||
201 | { | 199 | { | ||
202 | Q_ASSERT(!m_futureWatcher.isRunning()); | 200 | Q_ASSERT(!m_futureWatcher.isRunning()); | ||
203 | return m_data; | 201 | return m_data; | ||
204 | } | 202 | } | ||
205 | 203 | | |||
206 | #include "moc_cmakeimportjsonjob.cpp" | 204 | #include "moc_cmakeimportjsonjob.cpp" |