forked from qt-creator/qt-creator
Axivion: Tweak fetch for issues
Fetch issues for all kinds of issues instead of just style violations. Change-Id: I23508ae3c051cabab644f359daec4924034cb65c Reviewed-by: Andreas Loth <andreas.loth@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -53,21 +53,6 @@ using namespace Utils;
|
|||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
class Issue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QString id;
|
|
||||||
QString state;
|
|
||||||
QString errorNumber;
|
|
||||||
QString message;
|
|
||||||
QString entity;
|
|
||||||
QString filePath;
|
|
||||||
QString severity;
|
|
||||||
int lineNumber = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
using Issues = QList<Issue>;
|
|
||||||
|
|
||||||
QIcon iconForIssue(const QString &prefix)
|
QIcon iconForIssue(const QString &prefix)
|
||||||
{
|
{
|
||||||
static QHash<QString, QIcon> prefixToIcon;
|
static QHash<QString, QIcon> prefixToIcon;
|
||||||
@@ -154,7 +139,7 @@ public:
|
|||||||
void onDocumentOpened(IDocument *doc);
|
void onDocumentOpened(IDocument *doc);
|
||||||
void onDocumentClosed(IDocument * doc);
|
void onDocumentClosed(IDocument * doc);
|
||||||
void clearAllMarks();
|
void clearAllMarks();
|
||||||
void handleIssuesForFile(const Issues &issues);
|
void handleIssuesForFile(const Dto::FileViewDto &fileView);
|
||||||
void fetchIssueInfo(const QString &id);
|
void fetchIssueInfo(const QString &id);
|
||||||
|
|
||||||
NetworkAccessManager m_networkAccessManager;
|
NetworkAccessManager m_networkAccessManager;
|
||||||
@@ -173,16 +158,16 @@ static AxivionPluginPrivate *dd = nullptr;
|
|||||||
class AxivionTextMark : public TextMark
|
class AxivionTextMark : public TextMark
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AxivionTextMark(const FilePath &filePath, const Issue &issue)
|
AxivionTextMark(const FilePath &filePath, const Dto::LineMarkerDto &issue)
|
||||||
: TextMark(filePath, issue.lineNumber, {Tr::tr("Axivion"), AxivionTextMarkId})
|
: TextMark(filePath, issue.startLine, {Tr::tr("Axivion"), AxivionTextMarkId})
|
||||||
{
|
{
|
||||||
const QString markText = issue.entity.isEmpty() ? issue.message
|
const QString markText = issue.description;
|
||||||
: issue.entity + ": " + issue.message;
|
const QString id = issue.kind + QString::number(issue.id.value_or(-1));
|
||||||
setToolTip(issue.errorNumber + " " + markText);
|
setToolTip(id + markText);
|
||||||
setIcon(iconForIssue("SV")); // FIXME adapt to the issue
|
setIcon(iconForIssue(issue.kind));
|
||||||
setPriority(TextMark::NormalPriority);
|
setPriority(TextMark::NormalPriority);
|
||||||
setLineAnnotation(markText);
|
setLineAnnotation(markText);
|
||||||
setActionsProvider([id = issue.id] {
|
setActionsProvider([id] {
|
||||||
auto action = new QAction;
|
auto action = new QAction;
|
||||||
action->setIcon(Utils::Icons::INFO.icon());
|
action->setIcon(Utils::Icons::INFO.icon());
|
||||||
action->setToolTip(Tr::tr("Show rule details"));
|
action->setToolTip(Tr::tr("Show rule details"));
|
||||||
@@ -495,6 +480,17 @@ Group issueTableRecipe(const IssueListSearch &search, const IssueTableHandler &h
|
|||||||
return fetchDataRecipe<Dto::IssueTableDto>(url, handler);
|
return fetchDataRecipe<Dto::IssueTableDto>(url, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group lineMarkerRecipe(const Utils::FilePath &filePath, const LineMarkerHandler &handler)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(dd->m_currentProjectInfo, return {}); // TODO: Call handler with unexpected?
|
||||||
|
QTC_ASSERT(!filePath.isEmpty(), return {}); // TODO: Call handler with unexpected?
|
||||||
|
|
||||||
|
const QString fileName = QString::fromUtf8(QUrl::toPercentEncoding(filePath.path()));
|
||||||
|
const QUrl url = urlForProject(dd->m_currentProjectInfo.value().name + '/')
|
||||||
|
.resolved(QString("files?filename=" + fileName));
|
||||||
|
return fetchDataRecipe<Dto::FileViewDto>(url, handler);
|
||||||
|
}
|
||||||
|
|
||||||
Group issueHtmlRecipe(const QString &issueId, const HtmlHandler &handler)
|
Group issueHtmlRecipe(const QString &issueId, const HtmlHandler &handler)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(dd->m_currentProjectInfo, return {}); // TODO: Call handler with unexpected?
|
QTC_ASSERT(dd->m_currentProjectInfo, return {}); // TODO: Call handler with unexpected?
|
||||||
@@ -569,7 +565,7 @@ void AxivionPluginPrivate::fetchIssueInfo(const QString &id)
|
|||||||
dd->m_axivionOutputPane.updateAndShowRule(QString::fromUtf8(fixedHtml));
|
dd->m_axivionOutputPane.updateAndShowRule(QString::fromUtf8(fixedHtml));
|
||||||
};
|
};
|
||||||
|
|
||||||
m_issueInfoRunner.start(issueHtmlRecipe(QString("SV") + id, ruleHandler));
|
m_issueInfoRunner.start(issueHtmlRecipe(id, ruleHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionPluginPrivate::handleOpenedDocs()
|
void AxivionPluginPrivate::handleOpenedDocs()
|
||||||
@@ -591,41 +587,16 @@ void AxivionPluginPrivate::onDocumentOpened(IDocument *doc)
|
|||||||
if (!doc || !m_currentProjectInfo || !m_project || !m_project->isKnownFile(doc->filePath()))
|
if (!doc || !m_currentProjectInfo || !m_project || !m_project->isKnownFile(doc->filePath()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IssueListSearch search;
|
const FilePath filePath = doc->filePath().relativeChildPath(m_project->projectDirectory());
|
||||||
search.kind = "SV";
|
QTC_ASSERT(!filePath.isEmpty(), return);
|
||||||
search.filter_path = doc->filePath().relativeChildPath(m_project->projectDirectory()).path();
|
|
||||||
search.limit = 0;
|
|
||||||
|
|
||||||
const auto issuesHandler = [this](const Dto::IssueTableDto &dto) {
|
const auto handler = [this](const Dto::FileViewDto &data) {
|
||||||
Issues issues;
|
if (data.lineMarkers.empty())
|
||||||
const std::vector<std::map<QString, Dto::Any>> &rows = dto.rows;
|
return;
|
||||||
for (const auto &row : rows) {
|
handleIssuesForFile(data);
|
||||||
Issue issue;
|
|
||||||
for (auto it = row.cbegin(); it != row.cend(); ++it) {
|
|
||||||
if (it->first == "id")
|
|
||||||
issue.id = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "state")
|
|
||||||
issue.state = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "errorNumber")
|
|
||||||
issue.errorNumber = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "message")
|
|
||||||
issue.message = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "entity")
|
|
||||||
issue.entity = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "path")
|
|
||||||
issue.filePath = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "severity")
|
|
||||||
issue.severity = anyToSimpleString(it->second);
|
|
||||||
else if (it->first == "line")
|
|
||||||
issue.lineNumber = anyToSimpleString(it->second).toInt();
|
|
||||||
}
|
|
||||||
issues << issue;
|
|
||||||
}
|
|
||||||
handleIssuesForFile(issues);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TaskTree *taskTree = new TaskTree;
|
TaskTree *taskTree = new TaskTree;
|
||||||
taskTree->setRecipe(issueTableRecipe(search, issuesHandler));
|
taskTree->setRecipe(lineMarkerRecipe(filePath, handler));
|
||||||
m_docMarksTrees.insert_or_assign(doc, std::unique_ptr<TaskTree>(taskTree));
|
m_docMarksTrees.insert_or_assign(doc, std::unique_ptr<TaskTree>(taskTree));
|
||||||
connect(taskTree, &TaskTree::done, this, [this, doc] {
|
connect(taskTree, &TaskTree::done, this, [this, doc] {
|
||||||
const auto it = m_docMarksTrees.find(doc);
|
const auto it = m_docMarksTrees.find(doc);
|
||||||
@@ -653,24 +624,22 @@ void AxivionPluginPrivate::onDocumentClosed(IDocument *doc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionPluginPrivate::handleIssuesForFile(const Issues &issues)
|
void AxivionPluginPrivate::handleIssuesForFile(const Dto::FileViewDto &fileView)
|
||||||
{
|
{
|
||||||
if (issues.isEmpty())
|
if (fileView.lineMarkers.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Project *project = ProjectManager::startupProject();
|
Project *project = ProjectManager::startupProject();
|
||||||
if (!project)
|
if (!project)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const FilePath filePath = project->projectDirectory()
|
const FilePath filePath = project->projectDirectory().pathAppended(fileView.fileName);
|
||||||
.pathAppended(issues.first().filePath);
|
|
||||||
|
|
||||||
const Id axivionId(AxivionTextMarkId);
|
for (const Dto::LineMarkerDto &marker : std::as_const(fileView.lineMarkers)) {
|
||||||
for (const Issue &issue : issues) {
|
|
||||||
// FIXME the line location can be wrong (even the whole issue could be wrong)
|
// FIXME the line location can be wrong (even the whole issue could be wrong)
|
||||||
// depending on whether this line has been changed since the last axivion run and the
|
// depending on whether this line has been changed since the last axivion run and the
|
||||||
// current state of the file - some magic has to happen here
|
// current state of the file - some magic has to happen here
|
||||||
new AxivionTextMark(filePath, issue);
|
new AxivionTextMark(filePath, marker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,8 @@ namespace ProjectExplorer { class Project; }
|
|||||||
|
|
||||||
namespace Tasking { class Group; }
|
namespace Tasking { class Group; }
|
||||||
|
|
||||||
|
namespace Utils { class FilePath; }
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
struct IssueListSearch
|
struct IssueListSearch
|
||||||
@@ -57,6 +59,10 @@ Tasking::Group tableInfoRecipe(const QString &prefix, const TableInfoHandler &ha
|
|||||||
using IssueTableHandler = std::function<void(const Dto::IssueTableDto &)>;
|
using IssueTableHandler = std::function<void(const Dto::IssueTableDto &)>;
|
||||||
Tasking::Group issueTableRecipe(const IssueListSearch &search, const IssueTableHandler &handler);
|
Tasking::Group issueTableRecipe(const IssueListSearch &search, const IssueTableHandler &handler);
|
||||||
|
|
||||||
|
// TODO: Wrap into expected_str<>?
|
||||||
|
using LineMarkerHandler = std::function<void(const Dto::FileViewDto &)>;
|
||||||
|
Tasking::Group lineMarkerRecipe(const Utils::FilePath &filePath, const LineMarkerHandler &handler);
|
||||||
|
|
||||||
using HtmlHandler = std::function<void(const QByteArray &)>;
|
using HtmlHandler = std::function<void(const QByteArray &)>;
|
||||||
Tasking::Group issueHtmlRecipe(const QString &issueId, const HtmlHandler &handler);
|
Tasking::Group issueHtmlRecipe(const QString &issueId, const HtmlHandler &handler);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user