25#include <QCoreApplication>
31MakeAstRunner::MakeAstRunner(QObject *parent)
32 : QObject(parent), process_(new QProcess(this)) {
33 connect(process_, &QProcess::finished,
this,
34 &MakeAstRunner::onProcessFinished);
35 connect(process_, &QProcess::errorOccurred,
this,
36 &MakeAstRunner::onProcessError);
37 connect(process_, &QProcess::readyReadStandardOutput,
this,
38 &MakeAstRunner::onProcessStdOut);
39 connect(process_, &QProcess::readyReadStandardError,
this,
40 &MakeAstRunner::onProcessStdErr);
43MakeAstRunner::~MakeAstRunner() {
44 if (process_->state() != QProcess::NotRunning) {
46 process_->waitForFinished();
51 const QString &sourceFilePath,
52 const QString &outputFilePath,
53 const QString &makeAstBinary) {
55 emit
error(
"make-ast is already running");
59 sourceFilePath_ = sourceFilePath;
60 outputFilePath_ = outputFilePath;
63 QString binaryPath = makeAstBinary;
64 if (binaryPath.isEmpty()) {
66 QString appDir = QCoreApplication::applicationDirPath();
67 binaryPath = appDir +
"/make-ast";
70 QFileInfo sourceInfo(sourceFilePath);
71 emit
progress(
"Generating AST for " + sourceInfo.fileName() +
"...");
75 QStringList arguments;
76 arguments <<
"--compilation-database" << compilationDatabasePath;
77 arguments <<
"--source" << sourceFilePath;
78 arguments <<
"--output" << outputFilePath;
79 if (!clangResourceDir_.isEmpty()) {
80 arguments <<
"--clang-resource-dir" << clangResourceDir_;
83 qDebug() <<
"Running:" << binaryPath << arguments.join(
" ");
86 process_->start(binaryPath, arguments);
90 return process_->state() != QProcess::NotRunning;
95 process_->terminate();
107 return process_->waitForFinished(msecs);
112void MakeAstRunner::onProcessFinished(
int exitCode,
113 QProcess::ExitStatus exitStatus) {
114 drainProcessOutput(process_, pendingStdout_, pendingStderr_,
"make-ast",
115 [
this](
const LogEntry &entry) { emit logMessage(entry); });
117 if (exitStatus != QProcess::NormalExit) {
118 emit error(
"make-ast process crashed");
123 emit error(QString(
"make-ast failed with exit code %1").arg(exitCode));
128 QFileInfo sourceInfo(sourceFilePath_);
129 const double seconds = elapsed_.isValid()
130 ?
static_cast<double>(elapsed_.elapsed()) / 1000.0
132 emit progress(QString(
"make-ast: %1s (%2)")
133 .arg(QString::number(seconds,
'f', 2))
134 .arg(sourceInfo.fileName()));
135 emit astReady(outputFilePath_);
138void MakeAstRunner::onProcessError(QProcess::ProcessError error) {
139 drainProcessOutput(process_, pendingStdout_, pendingStderr_,
"make-ast",
140 [
this](
const LogEntry &entry) { emit logMessage(entry); });
142 QString systemError = process_->errorString();
143 QString errorMessage;
145 case QProcess::FailedToStart:
146 errorMessage = QString(
"Failed to start make-ast: %1. Make sure it's in the "
147 "same directory as the app or in PATH.").arg(systemError);
149 case QProcess::Crashed:
150 errorMessage = QString(
"make-ast crashed: %1").arg(systemError);
152 case QProcess::Timedout:
153 errorMessage = QString(
"make-ast timed out: %1").arg(systemError);
155 case QProcess::ReadError:
156 errorMessage = QString(
"Error reading from make-ast: %1").arg(systemError);
158 case QProcess::WriteError:
159 errorMessage = QString(
"Error writing to make-ast: %1").arg(systemError);
162 errorMessage = QString(
"Unknown error running make-ast: %1").arg(systemError);
166 emit this->error(errorMessage);
167 emitErrorLog(
"make-ast", errorMessage,
168 [
this](
const LogEntry &entry) { emit logMessage(entry); });
171void MakeAstRunner::onProcessStdOut() {
172 emitParsedOutput(pendingStdout_,
173 QString::fromUtf8(process_->readAllStandardOutput()),
175 [
this](
const LogEntry &entry) { emit logMessage(entry); });
178void MakeAstRunner::onProcessStdErr() {
179 emitParsedOutput(pendingStderr_,
180 QString::fromUtf8(process_->readAllStandardError()),
182 [
this](
const LogEntry &entry) { emit logMessage(entry); });
Qt runner for make-ast tool execution.
Helpers for draining process output into log entries.
bool waitForFinished(int msecs=30000)
Waits for the process to finish.
void run(const QString &compilationDatabasePath, const QString &sourceFilePath, const QString &outputFilePath, const QString &makeAstBinary=QString())
Run make-ast tool for specified source file.
void error(const QString &errorMessage)
Emitted when an error occurs.
void terminate()
Attempts to terminate the process gracefully Sends SIGTERM on Unix/macOS, WM_CLOSE on Windows.
void kill()
Kills the process immediately Sends SIGKILL on Unix/macOS, forceful termination on Windows.
bool isRunning() const
Check if tool is currently running.
void progress(const QString &message)
Emitted with progress updates.