How to highlight problems created by a GlobalInspectionTool Follow
I have written a GlobalInspectionTool that run a SonarQube analysis and create ProblemDescriptor for each SonarQube issue. When creating the ProblemDescriptor the only possibility is to customize ProblemHighlightType but it seems to only affect "severity" icon in the Inspection Results view.
I would like to also have some visual feedback on the code, for example highlight lines with issues.
I discovered the ExternalAnnotator API but it seems that I will need to reimplement all my logic of running a SonarQube analysis. And because SonarQube analysis will always run on the full project (at least for now) I'm not interested by the "locality" of ExternalAnnotator.
Question: is there a simple way to set custom highlighting for problems created by a GlobalInspectionTool?
And if I finally have to use ExternalAnnotator, is there a way to reuse problems created by the GlobalInspectionTool? Something like "foreach problem of last inspection then create annotation".
N.B.: Code is publicly visible here: https://github.com/SonarSource/sonar-intellij
Please sign in to leave a comment.
you cannot with GlobalInspectionTool.
to achieve this you have to implement com.intellij.codeInspection.LocalInspectionTool
I'm really surprised that it can't be done with GlobalInspectionTool. Why would it be possible with LocalInspectionTool and not GlobalInspectionTool? Those 2 classes definitely refer to the same concepts - they even share the same name ("*InspectionTool").
JetBrains guys: do you confirm Oleg's answer?
The difference between GlobalInspectionTool and LocalInspectionTool is that GlobalInspectionTool runs only during the "Analyze | Inspect Code" action. This allows it to use the global reference graph of the inspected part of the program, which is too expensive to calculate during on-the-fly code analysis. If you don't need to use the global reference graph, you can simply convert your inspection into a LocalInspectionTool.
So yes, Oleg's answer is correct.
Thanks Dmitry for your confirmation.
Still, I'm really puzzled by the fact that one kind of analysis (LocalInspectionTool) makes it possible to give a visual feedback in the text editor, but not the other one (GlobalInspectionTool). Both are "inspections", so both should give the same visual feedback to the user. This means that for long running analyses, we must find a hack to use the LocalInspectionTool - which is really dirty in terms of design.
Followinf Oleg advices I also tried to use a LocalInspectionTool, but here are my concerns:
1) LocalInspectionTool seems to support both "Analyze | Inspect Code" action and on-the-fly. But it seems highlighting is only applied for problems created during on-the-fly analysis. For example if I open a file in an editor, then run "Analyze" action then no highlighting appears even if there are reported problems for the file. I have to trigger a on-the-fly analysis (the way I found is to start typing a few characters in the editor) then highlighting will appear.
2) As said by Fabrice main concern is that a SonarQube analysis is incompatible with "on-the-fly" analysis. SQ analysis may take between 10 seconds and 1 minute and LocalInspectionTool don't offer an API to start long running process in the background. With GlobalInspectionTool I was using a GlobalInspectionContextExtension::performPreRunActivities to execute the SQ analysis, then accessing the result in GlobalInspectionTool::checkFile.
I tried to split execution of LocalInspectionTool in two parts:
- "Analyze | Inspect Code" action would trigger a full SQ analysis, cache results, and create problems to have the inspection view populated
- "on-the-fly" mode will only access the cache, create problems to have highlighting
But again it is hard to tell LocalInspectionTool to run a SQ analysis once because LocalInspectionTool::inspectionStarted seems to be called several times. And I also had several UI lock issues that I didn't have when running SQ analysis from GlobalInspectionContextExtension::performPreRunActivities.
If LocalInspectionTool is the only way to go, can you please advise me on the best way to trigger a "long running analysis" once for all then create problems on each file? If this is of importance, the "long running analysis" is currently a Maven goal (mvn sonar:sonar) that is started using:
IMHO you should add support to sonar-runner to run analysis on ONE file only in a "preview/dryRun" modus. This would make incremental analysis in ide a piece of cake.
You may try to implement com.intellij.lang.annotation.ExternalAnnotator, it would start in batch mode together with other annotators in common inspection and if you would implement com.intellij.codeInspection.ex.UnfairLocalInspectionTool with help of com.intellij.codeInspection.ExternalAnnotatorInspectionVisitor you'll highlight errors in the editor.
Normally though tool should be a localInspectionTool to perfom tasks in the editor and in batch and if the tool needs long calculations, then it should do its job in batch mode only.
Another way would be to run long running analysis with GlobalInspectionTool, write the results to a IssueCache. Later on the LocalInspectionTool can read those results from the Cache and mark code in editor.
But you will still have same problem with incosistent markings, if you change the code, which you can only solve by dramatically reducing the calculation time to <1 sec per file ;)
In the current state we are indeed running the long process in a GlobalInspectionTool and populate a cache with the result. Then an ExternalAnnotator will consult this cache each time it is needed to create annotations. But as soon as a fie is changed then annotations are created at the wrong place.
As you said Oleg we would need the ability to analyse a single file in less than one second but the current SonarQube batch architecture is not compatible with this requirement. We will definitely work on it in the coming months but that means in the meantime that having a proper IntelliJ integration (in pair with Eclipse integration) will be hard.
Anyway thanks for your help.
So you expect user to run batch inspections rather often and when he forgets to do so he would loose results in the editor. I don't think that it is a good idea, really
As long as we don't support very quick analysis, or as long as IntelliJ doesn't have something similar to Eclipse markers (ie annotations that are created once and will follow peace of code they are attached to) I don't see any valid option to have highlighting on code. Or did I miss something?
IntelliJ supports range markers which follow to the position when you edit the document. You may create com.intellij.openapi.editor.markup.MarkupModel#addRangeHighlighter which would be preserved as long as the range is valid.
Good to know, thanks. I will try that during next week.
As long you dont reread from cache intellij keeps the text ranges in right place.
But this still does not create markings for new code.