我正在寫一個Java代碼分析代碼片段,它將查找方法中變量的用法。 (具體來說,一個全局類變量在一個方法中被讀寫的次數)。這可以使用JavaParser完成嗎?會有人有任何其他建議嗎?是否有人知道如何計算班級指標?他們可能處理類似的事情。分析方法中的變量。 JavaParser/ANTLR還是別的?
4
A
回答
2
謝謝你們。這兩個答案都指導我使用JAVAPARSER中的AST實現來解決這個問題。下面是一個代碼片段,幫助他人
class CatchNameExpr extends VoidVisitorAdapter {
HashMap<String, ArrayList<Integer>> variableLineNumMap;``
ArrayList<String> variableList;
boolean functionParsing = false;
public CatchNameExpr(ArrayList<String> classVariables) {
variableList=classVariables;
}
public void visit(MethodDeclaration method, Object arg) {
System.out.println("---------------");
System.out.println(method.getName());
System.out.println("---------------");
variableLineNumMap = new HashMap<String, ArrayList<Integer>>();
System.out.println();
functionParsing = true;
visit(method.getBody(),arg);
// Analyze lines for variable usage. Add to list of vars after checking if its read or written or unknown.
functionParsing = false;
}
public void visit(NameExpr n, Object arg) {
if(!functionParsing)
return;
//TODO: check if this var was declared above it, as a local var to the func. if yes, return
ArrayList<Integer> setOfLineNum;
System.out.println(n.getBeginLine()+" NameExpr " + n.getName());
if(!variableList.contains(n.getName()) || n.getName().length()==0)
return;
if (!variableLineNumMap.containsKey(n.getName()))
{
setOfLineNum = new ArrayList<Integer>();
setOfLineNum.add(n.getBeginLine());
variableLineNumMap.put(n.getName(), setOfLineNum);
}
else
{
setOfLineNum = variableLineNumMap.get(n.getName());
setOfLineNum.add(n.getBeginLine());
variableLineNumMap.put(n.getName(), setOfLineNum);
}
}
}
實例化類--->
CatchNameExpr nameExp = new CatchNameExpr(classVariables);
nameExp.visit(classCompilationUnit, null);
以類似的方式,你可以訪問AST以下表達式,語句,條件等
我清楚地知道,字節碼處理器會更有效率,而且會做的工作比我更可期待。但是考慮到時間限制,這個選項讓我最滿意。
謝謝你們, Jasmeet
2
2
要問的問題是一個變量讀取是否是「全球性」或沒有,你需要一個相當於一個完整的Java編譯器的前端,它解析代碼,生成符號表和相關類型的信息。
編譯器在類文件實際上已記錄了該信息的範圍,您可以執行「反思」的操作讓你的手吧。如果這些信息存在於.class文件中,您可以使用類文件字節碼處理器訪問它,例如Kaigorodov答案中提到的處理器。
ANTLR有一個Java的語法,但我不相信,符號表建設的支持。 你不能假裝你自己; Java的規則太複雜了。您可能可以擴展ANTLR解析器來執行此操作,但這將是很多工作; 「Java的規則太複雜了」。
我瞭解Java編譯器提供某種名稱/類型的準確訪問其內部結構;你可能可以使用它。
我們的DMS軟件再造工具包擁有完整的Java解析器,與名稱和類型的分辨率,並且可以用於這一目的。
相關問題
- 1. Python如何知道類中的變量是方法還是變量?
- 2. 一對一的方法還是別的?
- 3. 是SonarQube分析增量還是?
- 4. 使用JavaParser分析變量的正確方法是什麼?
- 5. 在模板方法中,是否有方法檢查當前類型是int型變量還是float型變量?
- 6. 類別變量與方法變量
- 7. 將變量從php傳遞給js?還是更好的方法? 。
- 8. PHPStorm無法分析變量的路徑?
- 9. 這是分頁還是別的?
- 10. scikit的線性判別分析和Fisher判別分析法是相同的嗎?
- 11. 類別的變量方法名稱
- 12. 變量的方法級別範圍
- 13. 分析Android庫的方法數量
- 14. 無法批量分析變量
- 15. 解析方法變量名在Python中?
- 16. 變量還是常量?
- 17. Django ManyToMany Field還是別的?
- 18. Ruby中的變量分配是否真的很貴,還是它會優化鏈式字符串方法?
- 19. 迴歸分析還是Anova?
- 20. 在SASS中劃分變量的最簡單方法是什麼?
- 21. 本地方法變量,無法識別
- 22. 變量之間使用等號還是冒號的區別
- 23. PHP:分析變量
- 24. 這是擁有類級別成員變量的好方法嗎?
- 25. localStorage還是別的?
- 26. Haskell - 分析表達式中的變量的狀態(變量是否綁定?)
- 27. 查找方法中的方法數量並分別訪問每個方法
- 28. AdRequest.TEST_EMULATOR還是別的?
- 29. CA2000的級別變量和方法之間的區別警告
- 30. 無法解析私有方法中的變量
現在你與它的工作,你能告訴我,如果你有機會獲得一個類型的'Expression'的,不知何故? https://stackoverflow.com/questions/28851648/ – towi