From 7cb65b7f674ee9d04a03e6e6a56d0b33eae23f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 18 Jul 2020 18:14:55 +0200 Subject: [PATCH] GUI: Speedup code editor when selecting another warning in the same file --- gui/codeeditor.cpp | 13 +++++++++++++ gui/codeeditor.h | 24 ++++++++++++++++++++++++ gui/resultstree.cpp | 3 +++ gui/resultsview.cpp | 32 +++++++++++++++++++------------- gui/resultsview.h | 3 +++ lib/bughuntingchecks.cpp | 7 +++++-- 6 files changed, 67 insertions(+), 15 deletions(-) diff --git a/gui/codeeditor.cpp b/gui/codeeditor.cpp index a44e351c1..e7d6c6f07 100644 --- a/gui/codeeditor.cpp +++ b/gui/codeeditor.cpp @@ -257,6 +257,19 @@ void CodeEditor::setError(const QString &code, int errorLine, const QStringList highlightErrorLine(); } +void CodeEditor::setError(int errorLine, const QStringList &symbols) +{ + mHighlighter->setSymbols(symbols); + + mErrorPosition = getPos(toPlainText(), errorLine); + QTextCursor tc = textCursor(); + tc.setPosition(mErrorPosition); + setTextCursor(tc); + centerCursor(); + + highlightErrorLine(); +} + int CodeEditor::lineNumberAreaWidth() { int digits = 1; diff --git a/gui/codeeditor.h b/gui/codeeditor.h index 09fe523d0..3ed01d6b0 100644 --- a/gui/codeeditor.h +++ b/gui/codeeditor.h @@ -77,6 +77,29 @@ public: */ void setError(const QString &code, int errorLine, const QStringList &symbols); + /** + * Goto another error in existing source file + * \param errorLine line number + * \param symbols the related symbols, these are marked + */ + void setError(int errorLine, const QStringList &symbols); + + void setFileName(const QString &fileName) + { + mFileName = fileName; + } + + QString getFileName() const + { + return mFileName; + } + + void clear() + { + mFileName.clear(); + setPlainText(QString()); + } + protected: void resizeEvent(QResizeEvent *event) override; @@ -93,6 +116,7 @@ private: Highlighter *mHighlighter; CodeEditorStyle *mWidgetStyle; int mErrorPosition; + QString mFileName; }; diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index 392fc082e..191735c39 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -63,6 +63,7 @@ static const char LINE[] = "line"; static const char MESSAGE[] = "message"; static const char SEVERITY[] = "severity"; static const char SINCEDATE[] = "sinceDate"; +static const char SYMBOLNAMES[] = "symbolNames"; static const char SUMMARY[] = "summary"; static const char TAGS[] = "tags"; @@ -223,6 +224,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) data[FILE0] = stripPath(item.file0, true); data[FUNCTION] = item.function; data[SINCEDATE] = item.sinceDate; + data[SYMBOLNAMES] = item.symbolNames; data[TAGS] = line.tags; data[HIDE] = hide; stditem->setData(QVariant(data)); @@ -256,6 +258,7 @@ bool ResultsTree::addErrorItem(const ErrorItem &item) child_data[CWE] = line.cwe; child_data[CPPCHECKID] = line.cppcheckId; child_data[INCONCLUSIVE] = line.inconclusive; + child_data[SYMBOLNAMES] = item.symbolNames; child_item->setData(QVariant(child_data)); } } diff --git a/gui/resultsview.cpp b/gui/resultsview.cpp index e5cd359fa..35a5b5d96 100644 --- a/gui/resultsview.cpp +++ b/gui/resultsview.cpp @@ -385,9 +385,8 @@ void ResultsView::updateDetails(const QModelIndex &index) QStandardItemModel *model = qobject_cast(mUI.mTree->model()); QStandardItem *item = model->itemFromIndex(index); - mUI.mCode->setPlainText(QString()); - if (!item) { + mUI.mCode->clear(); mUI.mDetails->setText(QString()); return; } @@ -400,6 +399,7 @@ void ResultsView::updateDetails(const QModelIndex &index) // If there is no severity data then it is a parent item without summary and message if (!data.contains("severity")) { + mUI.mCode->clear(); mUI.mDetails->setText(QString()); return; } @@ -425,19 +425,25 @@ void ResultsView::updateDetails(const QModelIndex &index) if (!QFileInfo(filepath).exists() && QFileInfo(mUI.mTree->getCheckDirectory() + '/' + filepath).exists()) filepath = mUI.mTree->getCheckDirectory() + '/' + filepath; - QFile file(filepath); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QStringList symbols; - QRegularExpression re(".*: ([A-Za-z_][A-Za-z0-9_]*)$"); - const QString errorMessage = data["message"].toString(); - QRegularExpressionMatch match = re.match(errorMessage); - if (match.hasMatch()) { - symbols << match.captured(1); - } + QStringList symbols; + if (data.contains("symbolNames")) + symbols = data["symbolNames"].toString().split("\n"); - QTextStream in(&file); - mUI.mCode->setError(in.readAll(), lineNumber, symbols); + if (filepath == mUI.mCode->getFileName()) + { + mUI.mCode->setError(lineNumber, symbols); + return; } + + QFile file(filepath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + mUI.mCode->clear(); + return; + } + + QTextStream in(&file); + mUI.mCode->setError(in.readAll(), lineNumber, symbols); + mUI.mCode->setFileName(filepath); } void ResultsView::log(const QString &str) diff --git a/gui/resultsview.h b/gui/resultsview.h index 2332b429f..44871a266 100644 --- a/gui/resultsview.h +++ b/gui/resultsview.h @@ -359,6 +359,9 @@ private slots: void on_mListLog_customContextMenuRequested(const QPoint &pos); private: QSet mContracts; + + /** Current file shown in the code editor */ + QString mCurrentFileName; }; /// @} #endif // RESULTSVIEW_H diff --git a/lib/bughuntingchecks.cpp b/lib/bughuntingchecks.cpp index 3ba3643a6..82c7bdde9 100644 --- a/lib/bughuntingchecks.cpp +++ b/lib/bughuntingchecks.cpp @@ -352,10 +352,11 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine: const std::string inconclusiveMessage(inconclusive ? ". It is inconclusive if there would be a problem in the function call." : ""); if (!uninitStructMember.empty()) { + const std::string symbol = tok->expressionString() + "." + uninitStructMember; dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingUninitStructMember", - "Cannot determine that '" + tok->expressionString() + "." + uninitStructMember + "' is initialized" + inconclusiveMessage, + "$symbol:" + symbol + "\nCannot determine that '$symbol' is initialized" + inconclusiveMessage, CWE_USE_OF_UNINITIALIZED_VARIABLE, inconclusive, value.type == ExprEngine::ValueType::BailoutValue); @@ -366,10 +367,12 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine: if (uninitData) uninitexpr += "[0]"; + const std::string symbol = (tok->varId() > 0) ? ("$symbol:" + tok->str() + "\n") : std::string(); + dataBase->reportError(tok, Severity::SeverityType::error, "bughuntingUninit", - "Cannot determine that '" + uninitexpr + "' is initialized" + inconclusiveMessage, + symbol + "Cannot determine that '" + uninitexpr + "' is initialized" + inconclusiveMessage, CWE_USE_OF_UNINITIALIZED_VARIABLE, inconclusive, value.type == ExprEngine::ValueType::BailoutValue);