RCP: JDT 根據org.eclipse.jdt.core.IJavaElement對象獲取org.eclipse.jdt.core.dom.ASTNode對象


 

JDT中有兩套Java文件模型映射。

其核心類\接口分別為:

org.eclipse.jdt.core.IJavaElement和org.eclipse.jdt.core.dom.ASTNode

 

IJavaElement是Java Element的通用“協議”,即是對Java包、類、方法、變量、注解等等元素的規范。

它可以用於映射java文件,也可以映射class文件,任何java方面的元素都能找到其對應的實現類。

ASTNode是Java ast(語法分析樹)的建模,用於構建java語句,它只能用於java文件分析,對class文件無能為力。其側重點是語法。

 

舉個例子,一個類,比如java.util.List

在IJavaElement中要使用,必須有java.util.List作為IType存在。

在ASTNode中使用,則只需要用戶知道“java.util.List"這個字符串即可。

 

IJavaElement常用於分析Java相關的元素

ASTNode常用來解析和構建Java文件

 

在實際使用中,我們經常會涉及到兩個實現類之間的轉化。

比如根據IMethod來查找MethodDeclaration

 

JDT提供了一個方法的工具類NodeFinder。使用方式如下:

NodeFinder.perform(domUnit,
                        method.getSourceRange())

 

這里要特別注意的是sourceRange,它代表了指定對象(類、方法等)在java類定義里的儲存位置,它有兩個標量,offset和length。

所以,我們還可以使用以下方式:

 NodeFinder.perform(domUnit,mj.getOffset(),ms.getLength());


這里要特別注意的地方是,如果該method的源碼具備注釋(comment),該方法會產生問題,會找不到MethodDeclaration,取而代之的是父級的TypeDeclaration。

原因在於jdt(至少是3.7.0及更早版本)的BUG,IMethod記錄comment的offset和length,但是ASTNode並沒有相應的記錄,如果使用上方的方法,NodeFinder會認為范圍超限,屬於類范圍而非方法范圍。

 

所以,我們需要一個小小的改動:

IMethod method = (IMethod) methodElement
				.getAncestor(IJavaElement.METHOD);
		try {
			ISourceRange ms = method.getSourceRange();
			ISourceRange mj = method.getJavadocRange();

			if (ms.getOffset() == mj.getOffset()) {
				// 消除注釋的影響
				return (MethodDeclaration) NodeFinder.perform(domUnit,
						method.getSourceRange());
			} else {
				return (MethodDeclaration) NodeFinder.perform(domUnit,
						mj.getOffset(),
						ms.getLength() - mj.getOffset() + ms.getOffset());
			}
		} catch (JavaModelException e) {
			e.printStackTrace();
		}

 注意紅色部分,它用於去除多余的注釋部分,計算出准確的方法體范圍。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM