国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

擴展Eclipse的Java開發工具(四)

2019-11-18 13:01:15
字體:
來源:轉載
供稿:網友

  怎樣分析 java 代碼以進行修改?
  
  JDT 提供了幾個工具來幫助您分析代碼。本文有意選擇了最簡單的 IScanner 接口進行演示,它的作用域也最有限。這個接口屬于 JDT 工具箱,可以通過 JDT 的 ToolFactory 類訪問它。其 createScanner 方法返回一個掃描程序,該掃描程序會簡化對一串 Java 代碼作標記的工作。它不處理任何非凡困難的操作,只是對所返回的標記進行簡單的解析和分類。例如,它指出下一個標記是 public 要害字,其后的標記是一個標識符,再后面的標記是左圓括號,等等。隨后,只有當您希望分析一小段代碼(您明確理解想要在這段代碼中得到什么)時,這個掃描程序才是合適的。您決不會使用掃描程序分析整個 Java 源代碼;因為您會轉而使用一些對編譯器迷而言十分熟悉的工具:JDT 的抽象語法樹(Abstract Syntax Tree,AST)框架。
  
  與簡單的掃描程序不同,AST 理解語言元素(它們不再只是“標記”)之間的關系。它可以識別象局部變量、實例變量、表達式以及 if 語句等六十多種不同的語言元素。它將幫助您進行涉及范圍廣泛的重構,或難以滿足對標記進行一對一分類的模糊程度非凡高的重構。要更清楚地了解何時使用掃描程序與何時使用 AST 之間的差別,請考慮清單 10 中的代碼。
  
  清單 10. 模糊的變量引用
  
  public class Foo {
  int foo = 1;
  
  public int foo(int foo) {
  return foo + this.foo;
  }
  
  public int getFoo() {
  return foo;
  }
  }
  
  假如作為重構的一部分,您希望查找對實例變量 foo 的引用,那么就會明白一個單純的解析會使區分本地引用和實例變量引用成為一個難題。AST 創建了完整的分析樹,其中表示了 Java 源代碼的每個元素并對這些元素進行了區分。在這個特例中,不同的類會考慮“foo”引用的上下文,將“foo”引用表示成 AST 的節點(如 FieldDeclaration、SimpleName 和 ThisEXPRession),因此您會很輕松地識別它們。
  
  正如前面提到的,本文將只討論我們所選擇的簡單例子。對于比較復雜的修改和分析示例,請參閱參考資料一節。現在,讓我們回到我們前面跳過的用省略號表示的代碼。這個代碼將使用 IScanner 的實例以確定并替換源代碼中確定成員可視性的要害字。我們將處理的可視性修飾符是 public、private、protected 和 final。通過采用“蠻力”方法,我們可以簡化這個解決方案,即,采用兩個步驟就可以完成。首先刪除方法特征符中所有的可視性修飾符(或至少掃描查找它們,假如找到,就刪除),然后插入所希望的修飾符。非凡地:
  
  假如在方法特征符中找到 public、private 或 protected,就刪除它們。
  
  插入所請求的可視性修飾符(對于包可視性的情況,不作任何操作,因為這是缺省操作;即沒有任何修飾符)。
  
  final 修飾符很簡單。因為所希望的行為就是插入和除去這個修飾符,所以假如它存在,我們除去它;否則就插入它。清單 11 中的代碼只顯示了一個例子,它無條件地將成員的可視性從 pubilc 改成 private。在與本文相關的解決方案中,您將看到每個操作的公共代碼都被移到了抽象超類中。它基本上與下面的代碼相同,只不過稍作了整理以避免冗余。
  
  清單 11. 掃描是否有 pubilc 要害字
  
  ICompilationUnit cu = member.getCompilationUnit();
  
  if (cu.isWorkingCopy()) {
  IBuffer buffer = cu.getBuffer();
  
  IScanner scanner =
  ToolFactory.createScanner(false, false, false, false);
  scanner.setSource(buffer.getCharacters());
  ISourceRange sr = member.getSourceRange();
  scanner.resetTo(
  sr.getOffset(),
  sr.getOffset() + sr.getLength() - 1);
  
  int token = scanner.getNextToken();
  while (token != ITerminalSymbols.TokenNameEOF
  && token != ITerminalSymbols.TokenNameLPAREN)
  token = scanner.getNextToken();
  
  if (token == ITerminalSymbols.TokenNamePUBLIC) {
  buffer.replace(
  scanner.getCurrentTokenStartPosition(),
  scanner.getCurrentTokenEndPosition(),
  scanner.getCurrentTokenStartPosition() + 1,
  "private");
  break;
  }
  }
  cu.reconcile();
  }
  
  注:ITerminalSymbols 定義了掃描程序可以返回的標記名稱,它們對應于 Java 語法的標準標記。您可以進一步查詢掃描程序以詢問當前標記在緩沖區中開始和結束的具體位置,它出現在哪一行上,當然還有標記本身(非凡是象 ITerminalSymbols.TokenNameStringLiteral 和 ITerminalSymbols.TokenNameIdentifier 這樣的例子,它們不是保留的要害字)。
  
  上述代碼片段中,向 scanner.setSource 方法提供了編譯單元的完整源代碼,即 Java 源文件中的所有內容。正如前面提到的,掃描程序并不非常適合于大型分析,所以我們必須將它限制用于只有以目標方法的第一個字符開始,一直到調用 setSourceRange 方法作為結束的那部分源代碼。IMember 接口繼續了 ISourceReference,ISourceReference 是一個答應您查詢包含編譯單元內的源代碼字符串和源代碼位置的接口。這使我們不必確定目標方法在 Java 源代碼內開始和結束的位置。原本可以用 AST 實現這一點,而 ISourceReference 接口使 AST 成了多余的工具。由于 Java 方法特征符易于解析,所以 IScanner 接口的解析能力和它很匹配。我們必須做的就是查找 public 要害字,它出現在方法聲明的前一個字符之后,參數聲明的左圓括號之前,用 private 要害字替換它。當然,在該解決方案中,這個接口將處理所有的可能情況,不管該方法最初是 public、private、protected 還是 package(缺省)。
  
  下一步是什么?
  
  本文設定的目標是向您提供一個對 Eclipse 的 Java 開發環境頗具價值的擴展,這樣的擴展增強了這個開發環境的生產率。坦率地說,出于簡潔性考慮,我多次跳過了一些細節。該解決方案本身就作了一些簡化假設,象只答應在編輯器中對已打開的 Java 源代碼進行修改。您可能希望在更完整的實現中取消這個限制。
  
  雖然如此,但我還是希望您能感受到什么是可能的,并確信這樣做不是非凡困難。本文中我們討論的是 The Java Developer's Guide to Eclipse 一書某一高級章節的部分內容。該書中有十一個比較淺顯的章節討論了插件開發的基礎。象本文一樣,大多數章節都包含了一個已文檔化的工作解決方案,它可以強化您所學到的知識,大多數內容是以本文中您已看到的相同風格編寫的(不過可能沒有以這么快的節奏進行討論!)。
  
  重要:您可能需要向工作空間添加必要的插件,這樣解決方案才能編譯和運行。選擇 Window > Preferences > Plug-in Development > Target Platform,然后選擇 Not in Workspace。這將確保解決方案所依靠的基礎插件在導入和重新編譯過程中可用。
  
  一旦導入完成,您可能需要切換至 Plug-in Development 透視圖,在 com.ibm.lab.soln.jdt.excerpt 項目中選擇 plugin.xml,然后選擇 Update Classpath。這將修改由于 Eclipse 安裝路徑和解決方案的安裝路徑不同所引起的編譯錯誤。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江西省| 台中市| 怀集县| 忻州市| 霍城县| 清丰县| 桃园市| 印江| 奈曼旗| 根河市| 璧山县| 天峨县| 湘乡市| 鱼台县| 徐闻县| 兴隆县| 云南省| 穆棱市| 高青县| 云林县| 旬邑县| 东辽县| 宜黄县| 思南县| 鄂温| 威信县| 庆城县| 儋州市| 信宜市| 安远县| 金山区| 襄汾县| 成安县| 新田县| 望奎县| 苍山县| 兴安盟| 四平市| 玛沁县| 南江县| 秭归县|