GUI: Speedup code editor when selecting another warning in the same file

This commit is contained in:
Daniel Marjamäki 2020-07-18 18:14:55 +02:00
parent 46d997cd71
commit 7cb65b7f67
6 changed files with 67 additions and 15 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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));
}
}

View File

@ -385,9 +385,8 @@ void ResultsView::updateDetails(const QModelIndex &index)
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(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)

View File

@ -359,6 +359,9 @@ private slots:
void on_mListLog_customContextMenuRequested(const QPoint &pos);
private:
QSet<QString> mContracts;
/** Current file shown in the code editor */
QString mCurrentFileName;
};
/// @}
#endif // RESULTSVIEW_H

View File

@ -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);