GlobalInspection - checkElement never called

已回答

Hello,

I'm trying to develop a simple Dialyzer support for the Elixir plugin. That is, integrate an external analysis tool with the inspection system.

The problem I've encountered is that

checkElement(refEntity: RefEntity, scope: AnalysisScope, manager: InspectionManager, globalContext: GlobalInspectionContext): Array<CommonProblemDescriptor>? {

is never called unless I choose "the Whole Project", but in that case it is called once with "refEntity: RefModule" which isn't any help here.

What I need is a refFile, so I can get a PsiFile from that and add problems.

When I run the inspection on a specific elixir file, a message box appears 'No suspicious code found. 1 files processed in 'File '.../lib/forth.ex;.

My code:

class DialyzerWarningInspection : GlobalInspectionTool() {


override fun checkElement(refEntity: RefEntity, scope: AnalysisScope, manager: InspectionManager, globalContext: GlobalInspectionContext): Array<CommonProblemDescriptor>? {
return if (refEntity is RefFile) {
// THIS IS NEVER CALLED
checkFile(refEntity.psiElement, manager, false).map2Array { it as CommonProblemDescriptor }
}
else arrayOf()
}
(...)
}

plugin.xml

<globalInspection displayName="Dialyzer warning"
enabledByDefault="true" groupName="Elixir"
implementationClass="org.elixir_lang.dialyzer.inspection.DialyzerWarningInspection"
language="Elixir" level="ERROR" shortName="DialyzerWarning"/>

If I override "runInspection" and add a breakpoint, I get this:

scope.fileCount == 1 and scope.files = empty collection, so I cannot even manually iterate over them

0

I managed to call checkFile by accepting a visitor on scope

override fun runInspection(scope: AnalysisScope, manager: InspectionManager, globalContext: GlobalInspectionContext, problemDescriptionsProcessor: ProblemDescriptionsProcessor) {
scope.accept(object : PsiElementVisitor() {
override fun visitFile(file: PsiFile) {
checkFile(file, manager, false)
}
})
super.runInspection(scope, manager, globalContext, problemDescriptionsProcessor)
}

And later:

     fun checkFile(file: PsiFile,
manager: InspectionManager,
isOnTheFly: Boolean): List<ProblemDescriptor> {
val problemsHolder = ProblemsHolder(manager, file, isOnTheFly)

// ...
// THIS DOES EXECUTE
problemsHolder.registerProblem(
file.firstChild, "Dialyzer error: ",
ProblemHighlightType.ERROR)

// ...
return problemsHolder.results
}

But the problems aren't shown in the editor ("No suspicious code found"). Clearly I'm missing something...

Please assist, any suggestions appreciated

I develop in:

IntelliJ IDEA 2020.2.1 (Ultimate Edition)
Build #IU-202.6948.69, built on August 24, 2020
Licensed to Jacek Gajek
Subscription is active until January 31, 2021
Runtime version: 11.0.8+10-b944.31 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Ubuntu 20.04
GC: ParNew, ConcurrentMarkSweep
Memory: 7916M
Cores: 12
Registry: undo.documentUndoLimit=9999, js.debugger.webconsole=false
Non-Bundled Plugins: Base64 for IDEA and Storm, BashSupport, Dilbert, IdeaVIM, IvyIDEA, Mongo Plugin, PlantUML integration, Statistic, YAML/Ansible support, br.com.matheusfm.jsonutils, com.alayouni.ansiHighlight, com.bluewaitor.tsReact, com.github.leomillon.uuidgenerator, com.intellij.apacheConfig, com.intellij.ideolog, AutoConstructor, REST Client plugin, com.euphoricity.gitignore, com.github.syuchan1005.ImageComment, com.intellij.bigdecimal-folding, com.linsage, com.moxun.plugin.s2v, de.u-mass.idea.copyConstructor, marcglasberg.HibernateInspectionsPlugin, com.intellij.jira, com.jetbrains.plugins.ini4idea, com.intellij.plugins.watcher, com.jinsihou.react.snippets, com.potterhsu.jsonviewer, com.sburlyaev.terminal.plugin, de.ax.powermode, luonq.ScrollFromSource, main.kotlin.com.jimschubert.intellij.swaggercodegen, net.seesharpsoft.intellij.plugins.csv, org.github.plugin.redis-simple, org.intellij.RegexpTester, mobi.hsz.idea.gitignore, org.zalando.intellij.swagger, org.sylfra.idea.plugins.linessorter, pl.lksztmczk.openinterminal, send2terminal, com.deadlock.scsyntax, com.ifengxue.plugin.jpa-support, com.intellij.react.css.modules, com.androhi.androiddrawableviewer, com.mistamek.drawablepreview.drawable-preview, com.bruce.intellijplugin.generatesetter, com.intellij.plugins.html.instantEditing, org.intellij.scala, com.jetbrains.php, org.jetbrains.plugins.ruby, Pythonid, net.ashald.envfile, ru.adelf.idea.dotenv, nl.rubensten.texifyidea

For plugin SDK and testing I use the latest commmunity edition (2020.2)

 

0

AFAIU Dialyzer is a standalone program, that could be run against specific set of input files, correct?

If you don't need GlobalInspection capabilities, then using com.intellij.lang.annotation.ExternalAnnotator with com.intellij.codeInspection.ex.ExternalAnnotatorBatchInspection might be much easier.

0

Thanks for a response. I'm totally new to plugin development and I would really like to know why my code doesn't work, though.

Correct (almost), Dialyzer is a standalone program, but all input files must compile as a unit, so usually it boils down to running it over entire module.

My requirements are:

- the inspection can be chosen from "Inspections" menu, just as all the others

- I want to implement some quick fixes in the future

- Inspections should be attached to code tokens (it's called PSI here?) not line numbers so when user adds a line above annotation wouldn't be off

Does "ExternalAnnotatorBatchInspection" have these features?

By the way, my inspection worked correctly when it was declared as a Local Inspection, but I decided that calling an external app on each keystroke isn't the best idea (no pun intended), so I've switched to a global one.

0

I've resolved my issue, I needed to call "addProblemElement" for each found problem,

for (problem in checkFile(file, manager, false, dialyzerErrors)) {
problemDescriptionsProcessor.addProblemElement(globalContext.refManager.getReference(file), problem)
}
1

请先登录再写评论。