File indexing completed on 2024-04-28 05:48:20

0001 #include "ce_service.h"
0002 
0003 #include <QtNetwork/QNetworkReply>
0004 
0005 #include <KConfigGroup>
0006 #include <KSharedConfig>
0007 #include <QJsonDocument>
0008 #include <QJsonObject>
0009 
0010 // static const char url[] = "http://localhost:10240/api/";
0011 
0012 CompilerExplorerSvc *CompilerExplorerSvc::instance()
0013 {
0014     static CompilerExplorerSvc s_instance;
0015     return &s_instance;
0016 }
0017 
0018 void CompilerExplorerSvc::changeUrl(const QString &newUrl)
0019 {
0020     bool initializing = url.isEmpty();
0021     url = newUrl;
0022 
0023     if (url.endsWith(QLatin1Char('/'))) {
0024         url.chop(1);
0025     }
0026 
0027     if (!url.endsWith(QLatin1String("/api"))) {
0028         url.append(QLatin1String("/api/"));
0029     }
0030 
0031     // Since the url has changed, we must refresh compilers/languages
0032     if (!initializing) {
0033         sendRequest(CompilerExplorer::Languages);
0034         sendRequest(CompilerExplorer::Compilers);
0035     }
0036 }
0037 
0038 void CompilerExplorerSvc::sendRequest(CompilerExplorer::Endpoints endpoint, const QString &additional)
0039 {
0040     QString endp = CompilerExplorer::endpointsToString.value(endpoint);
0041     QString requestUrl = url + endp + additional;
0042     QUrl url{requestUrl};
0043     QNetworkRequest req{url};
0044     req.setRawHeader("ACCEPT", "application/json");
0045     req.setRawHeader("Content-Type", "application/json");
0046 
0047     mgr->get(req);
0048 }
0049 
0050 void CompilerExplorerSvc::compileRequest(const QString &endpoint, const QByteArray &obj)
0051 {
0052     QString requestUrl = url + endpoint;
0053     QNetworkRequest req{QUrl{requestUrl}};
0054     req.setRawHeader("ACCEPT", "application/json");
0055     req.setRawHeader("Content-Type", "application/json");
0056     mgr->post(req, obj);
0057 }
0058 
0059 QNetworkReply *CompilerExplorerSvc::tooltipRequest(const QString &asmWord)
0060 {
0061     QNetworkRequest request;
0062     QString urlString = url;
0063     urlString += QStringLiteral("asm/") + asmWord;
0064     request.setRawHeader("ACCEPT", "application/json");
0065     request.setRawHeader("Content-Type", "application/json");
0066     request.setUrl(QUrl(urlString));
0067     return mgr->get(request);
0068 }
0069 
0070 CompilerExplorerSvc::~CompilerExplorerSvc()
0071 {
0072     delete mgr;
0073 }
0074 
0075 CompilerExplorerSvc::CompilerExplorerSvc(QObject *parent)
0076     : QObject(parent)
0077 {
0078     mgr = new QNetworkAccessManager(this);
0079     connect(mgr, &QNetworkAccessManager::finished, this, &CompilerExplorerSvc::slotNetworkReply);
0080 
0081     KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("kate_compilerexplorer"));
0082     changeUrl(cg.readEntry("kate_compilerexplorer_url", QStringLiteral("http://localhost:10240")));
0083 }
0084 
0085 void CompilerExplorerSvc::slotNetworkReply(QNetworkReply *reply)
0086 {
0087     const QString path = reply->url().path().split(QLatin1Char('/')).at(2);
0088     CompilerExplorer::Endpoints endpoint;
0089     if (path.startsWith(QLatin1String("compilers"))) {
0090         endpoint = CompilerExplorer::stringToEndpoint.value(QStringLiteral("compilers"));
0091     } else if (path.startsWith(QLatin1String("compiler"))) {
0092         endpoint = CompilerExplorer::stringToEndpoint.value(QStringLiteral("compiler"));
0093     } else if (path.startsWith(QStringLiteral("asm"))) {
0094         return;
0095     } else {
0096         endpoint = CompilerExplorer::stringToEndpoint.value(path);
0097     }
0098     const QByteArray data = reply->readAll();
0099 
0100     switch (endpoint) {
0101     case CompilerExplorer::Languages: {
0102         Q_EMIT languages(data);
0103         break;
0104     }
0105     case CompilerExplorer::Compilers:
0106         Q_EMIT compilers(data);
0107         break;
0108     case CompilerExplorer::CompilerCompile:
0109         Q_EMIT asmResult(data);
0110         break;
0111     }
0112 }
0113 
0114 QJsonDocument CompilerExplorerSvc::getCompilationOptions(const QString &source,
0115                                                          const QString &userArgs,
0116                                                          bool isIntel,
0117                                                          bool demangle,
0118                                                          bool stripUnusedLabels,
0119                                                          bool stripComments,
0120                                                          bool stripLibFuncs)
0121 {
0122     // opt obj
0123     QJsonObject optObj;
0124     optObj[QStringLiteral("userArguments")] = userArgs;
0125 
0126     // compiler options obj
0127     QJsonObject compilerObj;
0128     compilerObj[QStringLiteral("skipAsm")] = false;
0129     compilerObj[QStringLiteral("executorRequest")] = false;
0130 
0131     // add compileropts to opt obj
0132     optObj[QStringLiteral("compilerOptions")] = compilerObj;
0133 
0134     // filters
0135     QJsonObject filterObj;
0136     filterObj[QStringLiteral("binary")] = false;
0137     filterObj[QStringLiteral("commentOnly")] = stripComments;
0138     filterObj[QStringLiteral("demangle")] = demangle;
0139     filterObj[QStringLiteral("directives")] = true;
0140     filterObj[QStringLiteral("intel")] = isIntel;
0141     filterObj[QStringLiteral("labels")] = stripUnusedLabels;
0142     filterObj[QStringLiteral("execute")] = false;
0143     filterObj[QStringLiteral("libraryCode")] = stripLibFuncs;
0144 
0145     optObj[QStringLiteral("filters")] = filterObj;
0146 
0147     QJsonObject main;
0148     //    main["source"] = "int sum(){ return 2 + 2; }";
0149     main[QStringLiteral("source")] = source;
0150     main[QStringLiteral("options")] = optObj;
0151 
0152     QJsonDocument doc{main};
0153     return doc;
0154 }
0155 
0156 #include "moc_ce_service.cpp"