I'd like to report custom problems for Java files to the Problems View of Eclipse and provide Quick Fixes for them.
The standard way to do is to use the extension point org.eclipse.core.resources.markers
to declare a custom marker and add markers by calling org.eclipse.core.resources.IResource.createMarker(String)
. Then, one can use the extension point org.eclipse.ui.ide.markerResolution
to provide a Quick Fix for the custom markers.
The above approach is a language-independent method of creating and resolving resource markers. The downside is that I have to write some boilerplate code to resolve my custom Java problems. Instead, I'd like to be reuse IQuickFixProcessor
. That is, I'd like to resolve my custom Java markers using the extension point org.eclipse.jdt.ui.quickFixProcessors
. Using this extension point, I no longer have to parse the Java file in which the marker is found, I don't have to build the bindings and find the AST node covering the marker. If I don't reuse org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator
and its dependencies, I'll end up duplicating most of it.
How can I provide Quick Fixes for my custom Java markers using the JDT infrastructure?
Attempt 1:
I defined my custom marker as follows:
<extension
id="custom.marker"
name="Custom Java Problem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.jdt.core.problem"/>
<super type="org.eclipse.core.resources.problemmarker"/>
<super type="org.eclipse.core.resources.textmarker"/>
<persistent value="true"/>
</extension>
Then, I added instances of the above marker by invoking method IResource.createMarker("custom.marker")
.
Next, I defined a custom Quick Fix processor.
<extension
point="org.eclipse.jdt.ui.quickFixProcessors">
<quickFixProcessor
class="quickfixes.CustomQuickFixProcessor"
id="quickfixes.quickFixProcessor">
</quickFixProcessor>
</extension>
My custom markers show up in the Problems View of Eclipse, but when I right-click on a custom problem, the Quick Fix menu item is disabled.
Attempt 2:
I repalced IMarker marker = resource.createMarker("custom.marker");
by IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
. As a result of this change, when I right-click on a custom problem in the Problems View, the Quick Fix menu item becomes available, but, when I select it, a dialog pops up that says there is no fix available for the selected problem. However, I verified that CustomQuickFixProcessor.hasCorrections(ICompilationUnit, int)
gets called and returns true
, but, CustomQuickFixProcessor.getCorrections(IInvocationContext, IProblemLocation[])
doesn't get invoked.
Attempt 3:
Attempt 3 is a continuation of Attempt 2. I set the IJavaModelMarker.ID
of the custom marker as follows:
marker.setAttribute(IJavaModelMarker.ID, IProblem.ExternalProblemFixable);
Consequently, CustomQuickFixProcessor.getCorrections
gets called when I hover over my custom marker in the editor or click on the light-build on the left margin of the Java editor. However, when I select the marker in the Problems View, right-click on the marker, and select the Quick Fix menu item, CustomQuickFixProcessor.getCorrections
doesn't get called and a dialog appears saying that no Quick Fixes are available.
I ran JDT in debug mode to see why it doesn't call CustomQuickFixProcessor.getCorrections
when I invoke the Quick Fix from the Problems View. It turned out CorrectionMarkerResolutionGenerator.internalGetResolutions(IMarker)
finds no resolutions because CorrectionMarkerResolutionGenerator.hasProblem (context.getASTRoot().getProblems(), location)
doesn't find the custom problem in the AST of the compilation unit. I'm not sure how to associate my custom markers with the AST of the compilation unit.