rep*_*mer 14 java eclipse eclipse-jdt
我想将Eclipse文件的自定义问题报告给Eclipse的Problems View,并为它们提供快速修复.
标准方法是使用扩展点org.eclipse.core.resources.markers声明自定义标记并通过调用添加标记org.eclipse.core.resources.IResource.createMarker(String).然后,可以使用扩展点org.eclipse.ui.ide.markerResolution为自定义标记提供快速修复.
上述方法是一种与语言无关的创建和解析资源标记的方法.缺点是我必须编写一些样板代码来解决我的自定义Java问题.相反,我想重用IQuickFixProcessor.也就是说,我想使用扩展点解析我的自定义Java标记org.eclipse.jdt.ui.quickFixProcessors.使用此扩展点,我不再需要解析找到标记的Java文件,我不必构建绑定并找到覆盖标记的AST节点.如果我不重用org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator它及其依赖项,我最终会复制它的大部分内容.
如何使用JDT基础结构为我的自定义Java标记提供快速修复?
尝试1:
我将自定义标记定义如下:
<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>
Run Code Online (Sandbox Code Playgroud)
然后,我通过调用方法添加了上述标记的实例IResource.createMarker("custom.marker").
接下来,我定义了一个自定义Quick Fix处理器.
<extension
point="org.eclipse.jdt.ui.quickFixProcessors">
<quickFixProcessor
class="quickfixes.CustomQuickFixProcessor"
id="quickfixes.quickFixProcessor">
</quickFixProcessor>
</extension>
Run Code Online (Sandbox Code Playgroud)
我的自定义标记出现在Eclipse的Problems View中,但是当我右键单击自定义问题时,Quick Fix菜单项被禁用.
尝试2:
我重申IMarker marker = resource.createMarker("custom.marker");了IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);.作为此更改的结果,当我右键单击"问题视图"中的自定义问题时,"快速修复"菜单项变为可用,但是,当我选择它时,会弹出一个对话框,指出没有可用的选项问题.但是,我验证了CustomQuickFixProcessor.hasCorrections(ICompilationUnit, int)调用并返回true,但是,CustomQuickFixProcessor.getCorrections(IInvocationContext, IProblemLocation[])没有被调用.
尝试3:
尝试3是尝试2的延续.我IJavaModelMarker.ID按如下方式设置自定义标记:
marker.setAttribute(IJavaModelMarker.ID, IProblem.ExternalProblemFixable);
Run Code Online (Sandbox Code Playgroud)
因此,CustomQuickFixProcessor.getCorrections当我将鼠标悬停在编辑器中的自定义标记上时,或者单击Java编辑器左边缘的灯光构建时,会调用它.但是,当我在"问题视图"中选择标记时,右键单击标记,然后选择"快速修复"菜单项,CustomQuickFixProcessor.getCorrections不会调用,并出现一个对话框,说明没有可用的快速修复.
我在调试模式下运行JDT,看看CustomQuickFixProcessor.getCorrections当我从Problems View中调用Quick Fix时它没有调用的原因.结果CorrectionMarkerResolutionGenerator.internalGetResolutions(IMarker)发现没有解决方案,因为CorrectionMarkerResolutionGenerator.hasProblem (context.getASTRoot().getProblems(), location)没有在编译单元的AST中找到自定义问题.我不确定如何将自定义标记与编译单元的AST相关联.
在这篇文章和调试器的帮助下,我得到了这个工作.这是你要做的:
plugin.xml中
声明标记,以便扩展这三个现有标记(我认为一切都是必要的)
<extension
id="mymarker"
name="My Problem"
point="org.eclipse.core.resources.markers">
<super
type="org.eclipse.jdt.core.problem">
</super>
<super
type="org.eclipse.core.resources.problemmarker">
</super>
<super
type="org.eclipse.core.resources.textmarker">
</super>
<persistent
value="true">
</persistent>
</extension>
Run Code Online (Sandbox Code Playgroud)
Java的
创建标记时,设置IJavaModelMarker.ID字段非常重要,我认为此处列出了所有其他字段.
// Must match the "id" attribute from plugin.xml
String MY_MARKER_ID = "com.example.my.plugin.mymarker"
// Must not be -1 or any of the values in org.eclipse.jdt.core.compiler.IProblem
int MY_JDT_PROBLEM_ID = 1234
// ....
IMarker marker = resource.createMarker(MY_MARKER_ID);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
marker.setAttribute(IMarker.MESSAGE, msg);
marker.setAttribute(IMarker.CHAR_START, start);
marker.setAttribute(IMarker.CHAR_END, end);
marker.setAttribute(IJavaModelMarker.ID, MY_JDT_PROBLEM_ID);
Run Code Online (Sandbox Code Playgroud)
plugin.xml中
首先声明它plugin.xml.要确保你的申报正确id的handledMarkerTypes
<extension
point="org.eclipse.jdt.ui.quickFixProcessors">
<quickFixProcessor
class="com.example.my.plugin.ui.MyQuickFixProcessor"
id="org.eclipse.jdt.ui.text.correction.QuickFixProcessor"
name="My Quick Fix Processor">
<handledMarkerTypes>
<markerType
id="com.example.my.plugin.mymarker">
</markerType>
</handledMarkerTypes>
</quickFixProcessor>
</extension>
Run Code Online (Sandbox Code Playgroud)
Java的
这是快速修复处理器的基本框架.请注意,检查locations实际上是否有内容很重要.
如果你制作自己的标记类型(如上所述),我认为你可以硬编码hasCorrections返回true.但要保存并遵循约定检查它是否与您的jdt问题ID匹配.
public class MyQuickFixProcessor implements IQuickFixProcessor {
@Override
public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IProblemLocation[] locations) throws CoreException {
if (locations == null || locations.length == 0) {
// https://bugs.eclipse.org/444120 Eclipse can call this method without
// any locations, if a quick fix is requested without any problems.
return null;
}
IJavaCompletionProposal[] proposals = ...
//...
return proposals;
}
@Override
public boolean hasCorrections(ICompilationUnit unit, int problemId) {
return problemId == MY_JDT_PROBLEM_ID;
}
}
Run Code Online (Sandbox Code Playgroud)
你需要一个MY_JDT_PROBLEM_ID独特的!运行下面的代码,打印所有当前ID IProblem.选择这些数字中的相当大的范围,然后在该范围内选择您的ID.
Field[] fields = org.eclipse.jdt.core.compiler.IProblem.class.getFields();
List<Integer> ints = new ArrayList<>();
for (Field field : fields) {
ints.add(field.getInt(null));
}
sort(ints);
for (Integer integer : ints) {
System.out.printf("%16d %16o %16x%n", integer, integer, integer);
}
Run Code Online (Sandbox Code Playgroud)
我希望我记得一切.祝好运.
你的尝试1不会成功,原因是:
JDT UI 定义了以下扩展。
<extension
point="org.eclipse.ui.ide.markerResolution">
<markerResolutionGenerator
markerType="org.eclipse.jdt.core.problem"
class="org.eclipse.jdt.internal.ui.text.correction.CorrectionMarkerResolutionGenerator">
</markerResolutionGenerator>
Run Code Online (Sandbox Code Playgroud)
即来自JDT 的快速修复仅适用于markerType="org.eclipse.jdt.core.problem"。
尝试 2:即使在 JDT UI 实现中,也存在这样的情况:当 QuickFixProcessor#hasCorrections(...) 返回 true 但 QuickFixProcessor#getCorrections(...) 可能不会返回修复。这是因为我们总是为特定标记返回 true 或 false。然而,特定标记的所有实例可能不是“可修复的”。也许你遇到类似的事情?
尝试 3:您在标记上设置了哪些属性?由于CorrectionMarkerResolutionGenerator.hasProblem(...)检查它,您至少需要设置 IMarker.CHAR_START 属性。看一下
org.eclipse.jdt.internal.core.eval.RequestorWrapper.acceptProblem(CategorizedProblem, char[], int),这是在 JDT Core 中创建标记的地方。
| 归档时间: |
|
| 查看次数: |
2427 次 |
| 最近记录: |