KDevelop5/Problem Checker Framework: Difference between revisions

From KDE TechBase
(Created page with "'''KDevelop Problem Checker Framework''' The basic idea behind the framework is to free checker plugin developers from having to implement models, views for each and every to...")
 
m (Add syntaxhighlight)
 
(One intermediate revision by one other user not shown)
Line 5: Line 5:
There's also a status class so that the user can get feedback about the problem checker's progress.
There's also a status class so that the user can get feedback about the problem checker's progress.


'''NOTE:''' Status is not neccessary it's just for convenience, to show the progress to the user.
{{Note|Status is not neccessary it's just for convenience, to show the progress to the user.}}
It makes no sense in case of runtime checkers like Valgrind, since you have no way of knowing how long it will be running, or
It makes no sense in case of runtime checkers like Valgrind, since you have no way of knowing how long it will be running, or
how many problems it will find.
how many problems it will find.
Line 18: Line 18:


Header
Header
 
<syntaxhighlight lang="cpp">
  // QScopedPointer is a Qt smart pointer which deletes the pointer when execution goes out of scope.
  // QScopedPointer is a Qt smart pointer which deletes the pointer when execution goes out of scope.
  QScopedPointer<KDevelop::ProblemModel> m_model;
  QScopedPointer<KDevelop::ProblemModel> m_model;
  QScopedPointer<KDevelop::CheckerStatus> m_status;
  QScopedPointer<KDevelop::CheckerStatus> m_status;
</syntaxhighlight>


Constructor
Constructor
 
<syntaxhighlight lang="cpp">
  #include <interfaces/icore.h>
  #include <interfaces/icore.h>
  #include <interfaces/ilanguagecontroller.h>
  #include <interfaces/ilanguagecontroller.h>
Line 43: Line 44:
  ICore::self()->uiController()->registerStatus(m_status.data());
  ICore::self()->uiController()->registerStatus(m_status.data());
  }
  }
</syntaxhighlight>


On shutdown
On shutdown


<syntaxhighlight lang="cpp">
  Plugin::unload()
  Plugin::unload()
  {
  {
Line 51: Line 54:
  problemModelSet->removeModel(QStringLiteral("CHECKER"));
  problemModelSet->removeModel(QStringLiteral("CHECKER"));
  }
  }
 
</syntaxhighlight>


During runtime the checker tool will find problems, and you will want to add those to the model.
During runtime the checker tool will find problems, and you will want to add those to the model.
Line 60: Line 63:
Creating problem instances
Creating problem instances


<syntaxhighlight lang="cpp">
  #include <shell/problem.h>
  #include <shell/problem.h>
   
   
Line 75: Line 79:
  range.setBothColumns(columnNumber);
  range.setBothColumns(columnNumber);
  problem->setFinalLocation(range);
  problem->setFinalLocation(range);
</syntaxhighlight>


Adding problems
Adding problems


<syntaxhighlight lang="cpp">
  // Typically with run-time checkers like Valgrind
  // Typically with run-time checkers like Valgrind
  m_model->addProblem(problem);
  m_model->addProblem(problem);
</syntaxhighlight>


or
or


<syntaxhighlight lang="cpp">
  // Typically static checkers like cppcheck, clang-check, pylint, jshint, etc.
  // Typically static checkers like cppcheck, clang-check, pylint, jshint, etc.
  QVector<IProblem::Ptr> problems;
  QVector<IProblem::Ptr> problems;
  m_model->setProblems(problems);
  m_model->setProblems(problems);
</syntaxhighlight>

Latest revision as of 18:39, 18 August 2019

KDevelop Problem Checker Framework

The basic idea behind the framework is to free checker plugin developers from having to implement models, views for each and every tool just to show problems in KDevelop. Instead of this, the developer just has to instantiate a ProblemModel and give it to KDevPlatform, which will show the problems added to it in the problems toolview, in it's own tab. There's also a status class so that the user can get feedback about the problem checker's progress.

Note
Status is not neccessary it's just for convenience, to show the progress to the user.

It makes no sense in case of runtime checkers like Valgrind, since you have no way of knowing how long it will be running, or how many problems it will find.

Using the framework

For using the framework the following steps must be taken

  • Instantiate a ProblemModel
  • (optional) Instantiate a CheckerStatus
  • Give the model to KDevPlatform
  • (optional) Give the status to KDevPlatform

Header

 // QScopedPointer is a Qt smart pointer which deletes the pointer when execution goes out of scope.
 QScopedPointer<KDevelop::ProblemModel> m_model;
 QScopedPointer<KDevelop::CheckerStatus> m_status;

Constructor

 #include <interfaces/icore.h>
 #include <interfaces/ilanguagecontroller.h>
 #include <interfaces/iuicontroller.h>
 #include <shell/problemmodelset.h>
 #include <shell/problemmodel.h>
 #include <shell/checkerstatus.h>
 
 ...
 
 Plugin::Plugin(parameters)
 	:m_model(new ProblemModel(parent))
 	,m_status(new CheckerStatus())
 {
 	m_status->setCheckerName(QStringLiteral("CHECKER")); // CHECKER is the name/label of the tool
 	ProblemModelSet *problemModelSet = ICore::self()->languageController()->problemModelSet();
 	problemModelSet->addModel(QStringLiteral("CHECKER"), m_model.data());
 	ICore::self()->uiController()->registerStatus(m_status.data());
 }

On shutdown

 Plugin::unload()
 {
 	ProblemModelSet *problemModelSet = ICore::self()->languageController()->problemModelSet();
 	problemModelSet->removeModel(QStringLiteral("CHECKER"));
 }

During runtime the checker tool will find problems, and you will want to add those to the model.

  • For every issue found, a Problem instance has to be created and filled with data
  • The problem(s) have to be added to the model


Creating problem instances

 #include <shell/problem.h>
 
 ...
 
 IProblem::Ptr problem(new DetectedProblem());
 problem->setDescription(shortMessage);
 problem->setExplanation(longMessage);
 problem->setSeverity(IProblem::Error);
 problem->setSource(IProblem::Plugin);
 
 DocumentRange range;
 range.document = IndexedString(filePath);
 range.setBothLines(lineNumber);
 range.setBothColumns(columnNumber);
 problem->setFinalLocation(range);

Adding problems

 // Typically with run-time checkers like Valgrind
 m_model->addProblem(problem);

or

 // Typically static checkers like cppcheck, clang-check, pylint, jshint, etc.
 QVector<IProblem::Ptr> problems;
 m_model->setProblems(problems);