// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "compiler.h" #include "config.h" #include #include #include #include #include #include namespace CompilerExplorer::Api { struct ExecuteParameters { ExecuteParameters &args(QStringList args) { obj["args"] = QJsonArray::fromStringList(args); return *this; } ExecuteParameters &stdIn(const QString &stdIn) { obj["stdin"] = stdIn; return *this; } QJsonObject obj; }; struct CompileParameters { CompileParameters() = delete; CompileParameters(const QString &cId) : compilerId(cId) { obj["compiler"] = cId; } CompileParameters(const Compiler &compiler) : compilerId(compiler.id) { obj["compiler"] = compiler.id; } QByteArray toByteArray() const { return QJsonDocument(obj).toJson(QJsonDocument::Compact); } struct Options { Options &userArguments(const QString &userArguments) { obj["userArguments"] = userArguments; return *this; } struct CompilerOptions { bool skipAsm{false}; bool executorRequest{false}; }; Options &compilerOptions(CompilerOptions compilerOptions) { QJsonObject co; co["skipAsm"] = compilerOptions.skipAsm; co["executorRequest"] = compilerOptions.executorRequest; obj["compilerOptions"] = co; return *this; } Options &executeParameters(ExecuteParameters executeParameters) { obj["executeParameters"] = executeParameters.obj; return *this; } struct Filters { bool binary{false}; bool binaryObject{false}; bool commentOnly{true}; bool demangle{true}; bool directives{true}; bool execute{false}; bool intel{true}; bool labels{true}; bool libraryCode{false}; bool trim{false}; bool debugCalls{false}; }; Options &filters(Filters filters) { QJsonObject filter; filter["binary"] = filters.binary; filter["binaryObject"] = filters.binaryObject; filter["commentOnly"] = filters.commentOnly; filter["demangle"] = filters.demangle; filter["directives"] = filters.directives; filter["execute"] = filters.execute; filter["intel"] = filters.intel; filter["labels"] = filters.labels; filter["libraryCode"] = filters.libraryCode; filter["trim"] = filters.trim; filter["debugCalls"] = filters.debugCalls; obj["filters"] = filter; return *this; } struct Libraries { QJsonArray array; Libraries &add(const QString id, const QString version) { QJsonObject obj; obj["id"] = id; obj["version"] = version; array.append(obj); return *this; } }; Options &libraries(const Libraries &libraries) { obj["libraries"] = libraries.array; return *this; } Options &libraries(const QMap &libraries) { Libraries result; for (auto it = libraries.begin(); it != libraries.end(); ++it) result.add(it.key(), *it); obj["libraries"] = result.array; return *this; } QJsonObject obj; }; CompileParameters &source(const QString &source) { obj["source"] = source; return *this; } CompileParameters &language(const QString &languageId) { obj["lang"] = languageId; return *this; } CompileParameters &options(Options options) { obj["options"] = options.obj; return *this; } QJsonObject obj; QString compilerId; }; struct CompilerResult { struct Line { QString text; struct Tag { int column; QString file; int line; int severity; QString text; static Tag fromJson(const QJsonObject &obj) { Tag tag; tag.column = obj["column"].toInt(); tag.file = obj["file"].toString(); tag.line = obj["line"].toInt(); tag.severity = obj["severity"].toInt(); tag.text = obj["text"].toString(); return tag; } }; std::optional tag; static Line fromJson(const QJsonObject &obj) { Line line; line.text = obj["text"].toString(); if (obj.contains("tag")) { line.tag = Tag::fromJson(obj["tag"].toObject()); } return line; } }; int code; bool timedOut; bool truncated; QList stdErr; QList stdOut; static CompilerResult fromJson(const QJsonObject &object) { CompilerResult result; result.timedOut = object["timedOut"].toBool(); result.truncated = object["truncated"].toBool(); result.code = object["code"].toInt(); for (const auto &line : object["stderr"].toArray()) result.stdErr.append(Line::fromJson(line.toObject())); for (const auto &line : object["stdout"].toArray()) result.stdOut.append(Line::fromJson(line.toObject())); return result; } }; struct CompileResult : CompilerResult { struct AssemblyLine { // A part of the asm that is a (hyper)link to a label (the name references labelDefinitions) struct Label { QString name; struct Range { int startCol; int endCol; } range; static Label fromJson(const QJsonObject &object) { Label label; label.name = object["name"].toString(); label.range.startCol = object["range"]["startCol"].toInt(); label.range.endCol = object["range"]["endCol"].toInt(); return label; } bool operator==(const Label &other) const { return name == other.name && range.startCol == other.range.startCol && range.endCol == other.range.endCol; } bool operator!=(const Label &other) const { return !(*this == other); } }; QList