mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-26 20:03:10 +00:00
258 lines
6.8 KiB
C++
258 lines
6.8 KiB
C++
![]() |
/* This file is part of KDevelop
|
||
|
Copyright 2007 Hamish Rodda <rodda@kde.org>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "problem.h"
|
||
|
|
||
|
#include "duchainregister.h"
|
||
|
#include "topducontextdynamicdata.h"
|
||
|
#include "topducontext.h"
|
||
|
#include "topducontextdata.h"
|
||
|
#include "duchain.h"
|
||
|
#include "duchainlock.h"
|
||
|
|
||
|
#include <interfaces/iassistant.h>
|
||
|
#include <KLocalizedString>
|
||
|
|
||
|
namespace KDevelop {
|
||
|
REGISTER_DUCHAIN_ITEM(Problem);
|
||
|
DEFINE_LIST_MEMBER_HASH(ProblemData, diagnostics, LocalIndexedProblem)
|
||
|
}
|
||
|
|
||
|
using namespace KDevelop;
|
||
|
|
||
|
LocalIndexedProblem::LocalIndexedProblem(const ProblemPointer& problem, const TopDUContext* top)
|
||
|
: m_index(problem->m_indexInTopContext)
|
||
|
{
|
||
|
ENSURE_CHAIN_READ_LOCKED
|
||
|
// ensure child problems are properly serialized before we serialize the parent problem
|
||
|
if (static_cast<uint>(problem->m_diagnostics.size()) != problem->d_func()->diagnosticsSize()) {
|
||
|
// see below, the diagnostic size is kept in sync by the mutable API of Problem
|
||
|
Q_ASSERT(!problem->diagnostics().isEmpty());
|
||
|
// the const cast is ugly but we don't really "change" the state as observed from the outside
|
||
|
auto& serialized = const_cast<Problem*>(problem.data())->d_func_dynamic()->diagnosticsList();
|
||
|
Q_ASSERT(serialized.isEmpty());
|
||
|
foreach(const ProblemPointer& child, problem->m_diagnostics) {
|
||
|
serialized << LocalIndexedProblem(child, top);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!m_index) {
|
||
|
m_index = top->m_dynamicData->allocateProblemIndex(problem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ProblemPointer LocalIndexedProblem::data(const TopDUContext* top) const
|
||
|
{
|
||
|
if (!m_index) {
|
||
|
return {};
|
||
|
}
|
||
|
return top->m_dynamicData->getProblemForIndex(m_index);
|
||
|
}
|
||
|
|
||
|
Problem::Problem()
|
||
|
: DUChainBase(*new ProblemData)
|
||
|
, m_topContext(nullptr)
|
||
|
, m_indexInTopContext(0)
|
||
|
{
|
||
|
d_func_dynamic()->setClassId(this);
|
||
|
}
|
||
|
|
||
|
Problem::Problem(ProblemData& data)
|
||
|
: DUChainBase(data)
|
||
|
, m_topContext(nullptr)
|
||
|
, m_indexInTopContext(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Problem::~Problem()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
TopDUContext* Problem::topContext() const
|
||
|
{
|
||
|
return m_topContext.data();
|
||
|
}
|
||
|
|
||
|
IndexedString Problem::url() const
|
||
|
{
|
||
|
return d_func()->url;
|
||
|
}
|
||
|
|
||
|
DocumentRange Problem::finalLocation() const
|
||
|
{
|
||
|
return DocumentRange(d_func()->url, rangeInCurrentRevision());
|
||
|
}
|
||
|
|
||
|
void Problem::setFinalLocation(const DocumentRange& location)
|
||
|
{
|
||
|
setRange(transformToLocalRevision(location));
|
||
|
d_func_dynamic()->url = location.document;
|
||
|
}
|
||
|
|
||
|
QList<ProblemPointer> Problem::diagnostics() const
|
||
|
{
|
||
|
return m_diagnostics;
|
||
|
}
|
||
|
|
||
|
void Problem::setDiagnostics(const QList<ProblemPointer>& diagnostics)
|
||
|
{
|
||
|
m_diagnostics = diagnostics;
|
||
|
// keep serialization in sync, see also LocalIndexedProblem ctor above
|
||
|
d_func_dynamic()->diagnosticsList().clear();
|
||
|
}
|
||
|
|
||
|
void Problem::addDiagnostic(const ProblemPointer& diagnostic)
|
||
|
{
|
||
|
m_diagnostics << diagnostic;
|
||
|
}
|
||
|
|
||
|
void Problem::clearDiagnostics()
|
||
|
{
|
||
|
m_diagnostics.clear();
|
||
|
// keep serialization in sync, see also LocalIndexedProblem ctor above
|
||
|
d_func_dynamic()->diagnosticsList().clear();
|
||
|
}
|
||
|
|
||
|
QString Problem::description() const
|
||
|
{
|
||
|
return d_func()->description.str();
|
||
|
}
|
||
|
|
||
|
void Problem::setDescription(const QString& description)
|
||
|
{
|
||
|
d_func_dynamic()->description = IndexedString(description);
|
||
|
}
|
||
|
|
||
|
QString Problem::explanation() const
|
||
|
{
|
||
|
return d_func()->explanation.str();
|
||
|
}
|
||
|
|
||
|
void Problem::setExplanation(const QString& explanation)
|
||
|
{
|
||
|
d_func_dynamic()->explanation = IndexedString(explanation);
|
||
|
}
|
||
|
|
||
|
ProblemData::Source Problem::source() const
|
||
|
{
|
||
|
return d_func()->source;
|
||
|
}
|
||
|
|
||
|
void Problem::setSource(ProblemData::Source source)
|
||
|
{
|
||
|
d_func_dynamic()->source = source;
|
||
|
}
|
||
|
|
||
|
KSharedPtr<IAssistant> Problem::solutionAssistant() const
|
||
|
{
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
ProblemData::Severity Problem::severity() const
|
||
|
{
|
||
|
return d_func()->severity;
|
||
|
}
|
||
|
|
||
|
void Problem::setSeverity(ProblemData::Severity severity)
|
||
|
{
|
||
|
d_func_dynamic()->severity = severity;
|
||
|
}
|
||
|
|
||
|
QString Problem::severityString() const
|
||
|
{
|
||
|
switch(severity()) {
|
||
|
case ProblemData::Error:
|
||
|
return i18n("Error");
|
||
|
case ProblemData::Warning:
|
||
|
return i18n("Warning");
|
||
|
case ProblemData::Hint:
|
||
|
return i18n("Hint");
|
||
|
}
|
||
|
return QString();
|
||
|
}
|
||
|
|
||
|
QString Problem::sourceString() const
|
||
|
{
|
||
|
switch (source()) {
|
||
|
case ProblemData::Disk:
|
||
|
return i18n("Disk");
|
||
|
case ProblemData::Preprocessor:
|
||
|
return i18n("Preprocessor");
|
||
|
case ProblemData::Lexer:
|
||
|
return i18n("Lexer");
|
||
|
case ProblemData::Parser:
|
||
|
return i18n("Parser");
|
||
|
case ProblemData::DUChainBuilder:
|
||
|
return i18n("Definition-Use Chain");
|
||
|
case ProblemData::SemanticAnalysis:
|
||
|
return i18n("Semantic Analysis");
|
||
|
case ProblemData::ToDo:
|
||
|
return i18n("TODO");
|
||
|
case ProblemData::Unknown:
|
||
|
default:
|
||
|
return i18n("Unknown");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QString Problem::toString() const
|
||
|
{
|
||
|
return QString("%1: %2 in %3:[(%4,%5),(%6,%7)]: %8 (found by %9)")
|
||
|
.arg(severityString())
|
||
|
.arg(description())
|
||
|
.arg(url().str())
|
||
|
.arg(range().start.line)
|
||
|
.arg(range().start.column)
|
||
|
.arg(range().end.line)
|
||
|
.arg(range().end.column)
|
||
|
.arg((explanation().isEmpty() ? QString("<no explanation>") : explanation()))
|
||
|
.arg(sourceString());
|
||
|
}
|
||
|
|
||
|
void Problem::rebuildDynamicData(DUContext* parent, uint ownIndex)
|
||
|
{
|
||
|
auto top = dynamic_cast<TopDUContext*>(parent);
|
||
|
Q_ASSERT(top);
|
||
|
|
||
|
m_topContext = top;
|
||
|
m_indexInTopContext = ownIndex;
|
||
|
|
||
|
// deserialize child diagnostics here, as the top-context might get unloaded
|
||
|
// but we still want to keep the child-diagnostics in-tact, as one would assume
|
||
|
// a shared-ptr works.
|
||
|
const auto data = d_func();
|
||
|
m_diagnostics.reserve(data->diagnosticsSize());
|
||
|
for (uint i = 0; i < data->diagnosticsSize(); ++i) {
|
||
|
m_diagnostics << ProblemPointer(data->diagnostics()[i].data(top));
|
||
|
}
|
||
|
|
||
|
DUChainBase::rebuildDynamicData(parent, ownIndex);
|
||
|
}
|
||
|
|
||
|
QDebug operator<<(QDebug s, const Problem& problem)
|
||
|
{
|
||
|
s.nospace() << problem.toString();
|
||
|
return s.space();
|
||
|
}
|
||
|
|
||
|
QDebug operator<<(QDebug s, const ProblemPointer& problem)
|
||
|
{
|
||
|
s.nospace() << problem->toString();
|
||
|
return s.space();
|
||
|
}
|