RedPanda-CPP/RedPandaIDE/compiler/compilermanager.cpp

363 lines
13 KiB
C++
Raw Normal View History

2021-04-20 22:24:33 +08:00
#include "compilermanager.h"
#include "filecompiler.h"
2021-06-24 20:43:09 +08:00
#include "stdincompiler.h"
2021-04-20 22:24:33 +08:00
#include "../mainwindow.h"
#include "executablerunner.h"
2021-11-01 09:18:23 +08:00
#include "ojproblemcasesrunner.h"
#include "utils.h"
2021-07-01 19:44:38 +08:00
#include "../settings.h"
2021-07-26 22:29:47 +08:00
#include <QMessageBox>
2021-09-13 22:45:50 +08:00
#include "projectcompiler.h"
#include "../platform.h"
2021-04-20 22:24:33 +08:00
2021-10-25 09:16:00 +08:00
enum RunProgramFlag {
RPF_PAUSE_CONSOLE = 0x0001,
RPF_REDIRECT_INPUT = 0x0002
};
2021-04-20 22:24:33 +08:00
CompilerManager::CompilerManager(QObject *parent) : QObject(parent)
{
mCompiler = nullptr;
mBackgroundSyntaxChecker = nullptr;
mRunner = nullptr;
2021-06-23 22:38:02 +08:00
mSyntaxCheckErrorCount = 0;
mSyntaxCheckIssueCount = 0;
2021-06-23 22:38:02 +08:00
mCompileErrorCount = 0;
mCompileIssueCount = 0;
mSyntaxCheckErrorCount = 0;
2021-04-20 22:24:33 +08:00
}
bool CompilerManager::compiling()
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mCompileMutex);
2021-04-20 22:24:33 +08:00
return mCompiler!=nullptr;
}
bool CompilerManager::backgroundSyntaxChecking()
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mBackgroundSyntaxCheckMutex);
2021-04-20 22:24:33 +08:00
return mBackgroundSyntaxChecker!=nullptr;
}
2021-06-25 12:40:11 +08:00
bool CompilerManager::running()
2021-04-20 22:24:33 +08:00
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mRunnerMutex);
return mRunner!=nullptr;
}
void CompilerManager::compile(const QString& filename, const QByteArray& encoding, bool rebuild, bool silent, bool onlyCheckSyntax)
{
2021-07-26 22:29:47 +08:00
if (!pSettings->compilerSets().defaultSet()) {
QMessageBox::critical(pMainWindow,
tr("No compiler set"),
tr("No compiler set is configured.")+tr("Can't start debugging."));
return;
2021-04-20 22:24:33 +08:00
}
if (pSettings->compilerSets().defaultSet()->compilerType() == "Clang"
&& (
(encoding!= ENCODING_ASCII && encoding!=ENCODING_UTF8)
|| (encoding == ENCODING_UTF8
&& pCharsetInfoManager->getDefaultSystemEncoding()!=ENCODING_UTF8)
)) {
QMessageBox::information(pMainWindow,
tr("Encoding not support"),
tr("Clang only support utf-8 encoding.")
+"<br />"
+tr("Strings in the program might be wrongly processed."));
}
2021-07-26 22:29:47 +08:00
{
QMutexLocker locker(&mCompileMutex);
if (mCompiler!=nullptr) {
return;
}
mCompileErrorCount = 0;
mCompileIssueCount = 0;
2021-07-26 22:29:47 +08:00
mCompiler = new FileCompiler(filename,encoding,silent,onlyCheckSyntax);
mCompiler->setRebuild(rebuild);
connect(mCompiler, &Compiler::finished, mCompiler, &QObject::deleteLater);
connect(mCompiler, &Compiler::compileFinished, this, &CompilerManager::onCompileFinished);
2021-07-26 22:29:47 +08:00
connect(mCompiler, &Compiler::compileIssue, this, &CompilerManager::onCompileIssue);
connect(mCompiler, &Compiler::compileStarted, pMainWindow, &MainWindow::onCompileStarted);
2021-09-13 22:45:50 +08:00
connect(mCompiler, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mCompiler, &Compiler::compileIssue, pMainWindow, &MainWindow::onCompileIssue);
connect(mCompiler, &Compiler::compileErrorOccured, pMainWindow, &MainWindow::onCompileErrorOccured);
mCompiler->start();
}
}
void CompilerManager::compileProject(std::shared_ptr<Project> project, bool rebuild, bool silent,bool onlyCheckSyntax)
{
if (!pSettings->compilerSets().defaultSet()) {
QMessageBox::critical(pMainWindow,
tr("No compiler set"),
tr("No compiler set is configured.")+tr("Can't start debugging."));
return;
}
{
QMutexLocker locker(&mCompileMutex);
if (mCompiler!=nullptr) {
return;
}
mCompileErrorCount = 0;
mCompileIssueCount = 0;
2021-09-13 22:45:50 +08:00
mCompiler = new ProjectCompiler(project,silent,onlyCheckSyntax);
mCompiler->setRebuild(rebuild);
connect(mCompiler, &Compiler::finished, mCompiler, &QObject::deleteLater);
connect(mCompiler, &Compiler::compileFinished, this, &CompilerManager::onCompileFinished);
2021-09-13 22:45:50 +08:00
connect(mCompiler, &Compiler::compileIssue, this, &CompilerManager::onCompileIssue);
connect(mCompiler, &Compiler::compileStarted, pMainWindow, &MainWindow::onCompileStarted);
2021-07-26 22:29:47 +08:00
connect(mCompiler, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mCompiler, &Compiler::compileIssue, pMainWindow, &MainWindow::onCompileIssue);
connect(mCompiler, &Compiler::compileErrorOccured, pMainWindow, &MainWindow::onCompileErrorOccured);
mCompiler->start();
}
}
void CompilerManager::cleanProject(std::shared_ptr<Project> project)
{
if (!pSettings->compilerSets().defaultSet()) {
QMessageBox::critical(pMainWindow,
tr("No compiler set"),
tr("No compiler set is configured.")+tr("Can't start debugging."));
return;
}
{
QMutexLocker locker(&mCompileMutex);
if (mCompiler!=nullptr) {
return;
}
mCompileErrorCount = 0;
mCompileIssueCount = 0;
ProjectCompiler* compiler = new ProjectCompiler(project,false,false);
compiler->setOnlyClean(true);
mCompiler = compiler;
mCompiler->setRebuild(false);
connect(mCompiler, &Compiler::finished, mCompiler, &QObject::deleteLater);
connect(mCompiler, &Compiler::compileFinished, this, &CompilerManager::onCompileFinished);
connect(mCompiler, &Compiler::compileIssue, this, &CompilerManager::onCompileIssue);
connect(mCompiler, &Compiler::compileStarted, pMainWindow, &MainWindow::onCompileStarted);
connect(mCompiler, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mCompiler, &Compiler::compileIssue, pMainWindow, &MainWindow::onCompileIssue);
connect(mCompiler, &Compiler::compileErrorOccured, pMainWindow, &MainWindow::onCompileErrorOccured);
mCompiler->start();
}
}
2021-09-17 19:58:37 +08:00
void CompilerManager::buildProjectMakefile(std::shared_ptr<Project> project)
{
if (!pSettings->compilerSets().defaultSet()) {
QMessageBox::critical(pMainWindow,
tr("No compiler set"),
tr("No compiler set is configured.")+tr("Can't start debugging."));
return;
}
{
QMutexLocker locker(&mCompileMutex);
if (mCompiler!=nullptr) {
return;
}
ProjectCompiler compiler(project,false,false);
compiler.buildMakeFile();
}
}
2021-09-12 22:45:00 +08:00
void CompilerManager::checkSyntax(const QString &filename, const QString &content, bool isAscii, std::shared_ptr<Project> project)
2021-06-24 20:43:09 +08:00
{
2021-07-26 22:29:47 +08:00
if (!pSettings->compilerSets().defaultSet()) {
QMessageBox::critical(pMainWindow,
tr("No compiler set"),
tr("No compiler set is configured.")+tr("Can't start debugging."));
2021-06-24 20:43:09 +08:00
return;
}
2021-07-26 22:29:47 +08:00
{
QMutexLocker locker(&mBackgroundSyntaxCheckMutex);
if (mBackgroundSyntaxChecker!=nullptr) {
return;
}
mSyntaxCheckErrorCount = 0;
mSyntaxCheckIssueCount = 0;
mBackgroundSyntaxChecker = new StdinCompiler(filename,content,isAscii,true,true);
2021-09-12 22:45:00 +08:00
mBackgroundSyntaxChecker->setProject(project);
connect(mBackgroundSyntaxChecker, &Compiler::finished, mBackgroundSyntaxChecker, &QThread::deleteLater);
2021-07-26 22:29:47 +08:00
connect(mBackgroundSyntaxChecker, &Compiler::compileIssue, this, &CompilerManager::onSyntaxCheckIssue);
connect(mBackgroundSyntaxChecker, &Compiler::compileStarted, pMainWindow, &MainWindow::onCompileStarted);
connect(mBackgroundSyntaxChecker, &Compiler::compileFinished, this, &CompilerManager::onSyntaxCheckFinished);
2021-07-26 22:29:47 +08:00
connect(mBackgroundSyntaxChecker, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mBackgroundSyntaxChecker, &Compiler::compileIssue, pMainWindow, &MainWindow::onCompileIssue);
connect(mBackgroundSyntaxChecker, &Compiler::compileErrorOccured, pMainWindow, &MainWindow::onCompileErrorOccured);
mBackgroundSyntaxChecker->start();
}
2021-06-24 20:43:09 +08:00
}
void CompilerManager::run(const QString &filename, const QString &arguments, const QString &workDir)
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mRunnerMutex);
if (mRunner!=nullptr) {
return;
}
QString redirectInputFilename;
bool redirectInput=false;
if (pSettings->executor().redirectInput()
&& !pSettings->executor().inputFilename().isEmpty()) {
redirectInput =true;
redirectInputFilename = pSettings->executor().inputFilename();
}
2021-11-01 09:18:23 +08:00
ExecutableRunner * execRunner;
2021-10-25 09:16:00 +08:00
if (programHasConsole(filename)) {
int consoleFlag=0;
if (redirectInput)
consoleFlag |= RPF_REDIRECT_INPUT;
if (pSettings->executor().pauseConsole())
consoleFlag |= RPF_PAUSE_CONSOLE;
if (consoleFlag!=0) {
QString newArguments = QString(" %1 \"%2\" %3")
.arg(consoleFlag)
.arg(toLocalPath(filename)).arg(arguments);
execRunner = new ExecutableRunner(includeTrailingPathDelimiter(pSettings->dirs().app())+"ConsolePauser.exe",newArguments,workDir);
} else {
execRunner = new ExecutableRunner(filename,arguments,workDir);
}
2021-11-01 09:18:23 +08:00
execRunner->setStartConsole(true);
} else {
2021-11-01 09:18:23 +08:00
execRunner = new ExecutableRunner(filename,arguments,workDir);
}
2021-10-25 09:16:00 +08:00
if (redirectInput) {
2021-11-01 09:18:23 +08:00
execRunner->setRedirectInput(true);
execRunner->setRedirectInputFilename(redirectInputFilename);
2021-10-25 09:16:00 +08:00
}
2021-11-01 09:18:23 +08:00
mRunner = execRunner;
connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
connect(mRunner, &Runner::finished, pMainWindow ,&MainWindow::onRunFinished);
connect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
mRunner->start();
}
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, POJProblemCase problemCase)
{
QMutexLocker locker(&mRunnerMutex);
if (mRunner!=nullptr) {
return;
}
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCase);
mRunner = execRunner;
connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
2021-11-01 20:44:08 +08:00
connect(mRunner, &Runner::finished, pMainWindow ,&MainWindow::onRunProblemFinished);
2021-11-01 09:18:23 +08:00
connect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
2021-11-01 20:44:08 +08:00
connect(execRunner, &OJProblemCasesRunner::caseStarted, pMainWindow, &MainWindow::onOJProblemCaseStarted);
connect(execRunner, &OJProblemCasesRunner::caseFinished, pMainWindow, &MainWindow::onOJProblemCaseFinished);
2021-11-01 09:18:23 +08:00
mRunner->start();
}
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, QVector<POJProblemCase> problemCases)
{
QMutexLocker locker(&mRunnerMutex);
if (mRunner!=nullptr) {
return;
}
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCases);
mRunner = execRunner;
connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
2021-11-01 20:44:08 +08:00
connect(mRunner, &Runner::finished, pMainWindow ,&MainWindow::onRunProblemFinished);
2021-11-01 09:18:23 +08:00
connect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
2021-11-01 20:44:08 +08:00
connect(execRunner, &OJProblemCasesRunner::caseStarted, pMainWindow, &MainWindow::onOJProblemCaseStarted);
connect(execRunner, &OJProblemCasesRunner::caseFinished, pMainWindow, &MainWindow::onOJProblemCaseFinished);
mRunner->start();
}
2021-06-25 12:40:11 +08:00
void CompilerManager::stopRun()
{
QMutexLocker locker(&mRunnerMutex);
if (mRunner!=nullptr)
mRunner->stop();
}
void CompilerManager::stopCompile()
{
QMutexLocker locker(&mCompileMutex);
if (mCompiler!=nullptr)
mCompiler->stopCompile();
}
void CompilerManager::stopCheckSyntax()
{
QMutexLocker locker(&mBackgroundSyntaxCheckMutex);
if (mBackgroundSyntaxChecker!=nullptr)
mBackgroundSyntaxChecker->stopCompile();
}
2021-10-20 18:05:43 +08:00
bool CompilerManager::canCompile(const QString &)
{
return !compiling();
2021-04-20 22:24:33 +08:00
}
void CompilerManager::onCompileFinished()
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mCompileMutex);
mCompiler=nullptr;
pMainWindow->onCompileFinished(false);
2021-04-20 22:24:33 +08:00
}
void CompilerManager::onRunnerTerminated()
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mRunnerMutex);
2021-11-01 09:18:23 +08:00
Runner* p=mRunner;
mRunner=nullptr;
2021-08-01 23:24:37 +08:00
p->deleteLater();
}
void CompilerManager::onCompileIssue(PCompileIssue issue)
{
if (issue->type == CompileIssueType::Error)
mCompileErrorCount++;
mCompileIssueCount++;
}
2021-06-24 20:43:09 +08:00
void CompilerManager::onSyntaxCheckFinished()
{
2021-06-25 12:40:11 +08:00
QMutexLocker locker(&mBackgroundSyntaxCheckMutex);
2021-06-24 20:43:09 +08:00
mBackgroundSyntaxChecker=nullptr;
pMainWindow->onCompileFinished(true);
2021-06-24 20:43:09 +08:00
}
void CompilerManager::onSyntaxCheckIssue(PCompileIssue issue)
2021-06-24 20:43:09 +08:00
{
if (issue->type == CompileIssueType::Error)
mSyntaxCheckErrorCount++;
if (issue->type == CompileIssueType::Error ||
issue->type == CompileIssueType::Warning)
mSyntaxCheckIssueCount++;
}
int CompilerManager::syntaxCheckIssueCount() const
{
return mSyntaxCheckIssueCount;
}
int CompilerManager::compileIssueCount() const
{
return mCompileIssueCount;
2021-06-24 20:43:09 +08:00
}
2021-06-23 22:38:02 +08:00
int CompilerManager::syntaxCheckErrorCount() const
{
return mSyntaxCheckErrorCount;
}
int CompilerManager::compileErrorCount() const
{
return mCompileErrorCount;
}
CompileError::CompileError(const QString &reason):BaseError(reason)
{
}