簡體   English   中英

如何為自定義Java標記添加Eclipse Quick Fix?

[英]How can I add an Eclipse Quick Fix for a custom Java marker?

我想將Eclipse文件的自定義問題報告給Eclipse的Problems View,並為它們提供快速修復。

標准方法是使用擴展點org.eclipse.core.resources.markers來聲明自定義標記並通過調用org.eclipse.core.resources.IResource.createMarker(String)添加標記。 然后,可以使用擴展點org.eclipse.ui.ide.markerResolution為自定義標記提供快速修復。

上述方法是一種與語言無關的創建和解析資源標記的方法。 缺點是我必須編寫一些樣板代碼來解決我的自定義Java問題。 相反,我想重用IQuickFixProcessor 也就是說,我想使用擴展點org.eclipse.jdt.ui.quickFixProcessors解析我的自定義Java標記。 使用此擴展點,我不再需要解析找到標記的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>

然后,我通過調用方法IResource.createMarker("custom.marker")添加了上述標記的實例。

接下來,我定義了一個自定義Quick Fix處理器。

<extension
  point="org.eclipse.jdt.ui.quickFixProcessors">
  <quickFixProcessor
    class="quickfixes.CustomQuickFixProcessor"
    id="quickfixes.quickFixProcessor">
  </quickFixProcessor>
</extension>

我的自定義標記出現在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);

因此,當我將鼠標懸停在編輯器中的自定義標記上或單擊Java編輯器左邊緣的燈光構建時,將調用CustomQuickFixProcessor.getCorrections 但是,當我在“問題視圖”中選擇標記時,右鍵單擊標記,然后選擇“快速修復”菜單項,不會調用CustomQuickFixProcessor.getCorrections並出現一個對話框,指出沒有可用的快速修復。

我在調試模式下運行JDT以查看當我從Problems視圖調用Quick Fix時它不調用CustomQuickFixProcessor.getCorrections原因。 事實證明, 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>

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);

創建QuickFixProcessor

plugin.xml中

首先在plugin.xml聲明它。 確保在handledMarkerTypes聲明正確的id

<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>

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;
  }
}

找到一個好的JDT ID

你需要一個獨一無二的MY_JDT_PROBLEM_ID 運行下面的代碼,打印IProblem定義的所有當前ID。 選擇這些數字中的相當大的范圍,然后在該范圍內選擇您的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);
}

我希望我記得一切。 祝好運。

您的嘗試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>

即來自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中的標記的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM