摘要:另載于本系列臨近尾聲,科技樹到此點滿。如果做插件,可以享受的語義分析能力。為了讓程序獨立運行,我自己按需實現了語義分析。為了提速分析大型代碼庫,可以手動限制范圍。直接貼代碼了,已在項目提供。
另載于 http://www.qingjingjie.com/blogs/6
本系列臨近尾聲,科技樹到此點滿。
語法分析主要用庫解決了,代碼變成了一棵樹,但是變量類型,方法簽名之類的東東都不清楚。
如果做IDE插件,可以享受IDE的語義分析能力。為了讓程序獨立運行,我自己按需實現了語義分析。
比較復雜,就分享一種最典型的吧。貼代碼為主,有問題請告訴我,我再改文章。
解析某個變量的聲明類型,會上溯當前方法和類,以及祖先類。為了提速(分析大型代碼庫),可以手動限制范圍。
直接貼代碼了,已在Exia項目提供。
public class VariableTypeResolver { private final String symbol; private final ASTNode minScope; private boolean methodLevel = true; private boolean typeLevel = true; /** * The found result */ private SimpleName declSN; private final ASTVisitor visitor = new ASTVisitor() { @Override public boolean visit(SimpleName sn) { if (found()) { return false; } if (sn.getIdentifier().equals(symbol) && sn.getParent() instanceof VariableDeclaration) { declSN = sn; return false; } return true; } }; /** * Starts resolving with the requested symbol * @param varSymbolNode the variable symbol node to resolve (node must be in the AST) */ public VariableTypeResolver(SimpleName varSymbolNode) { this.symbol = varSymbolNode.getIdentifier(); this.minScope = varSymbolNode; } public VariableTypeResolver(String varSymbol, ASTNode minScope) { this.symbol = varSymbol; this.minScope = minScope; } public VariableTypeResolver disableMethodLevel() { methodLevel = false; return this; } public VariableTypeResolver disableTypeLevel() { typeLevel = false; return this; } /** * Node"s parent is instance of {@link VariableDeclarationFragment} or {@link SingleVariableDeclaration} * @return the SimpleName node of declaration */ public SimpleName resolveDeclSimpleName() { if (!found()) { resolve(); } return declSN; } private void resolve() { if(found()) {return;} if (methodLevel) { apply(FindUpper.methodScope(minScope)); } if(found()) {return;} if (typeLevel) { AbstractTypeDeclaration typeScope = FindUpper.abstractTypeScope(minScope); applyInFields(typeScope); if(found()) {return;} for (TypeDeclaration superClass : superClasses(typeScope)) { if(found()) {return;} applyInFields(superClass); } } } private boolean found() { return declSN != null; } private void apply(ASTNode scope) { if (scope == null) { throw new NullPointerException(); } scope.accept(visitor); } private void applyInFields(AbstractTypeDeclaration typeScope) { for (Object bd : typeScope.bodyDeclarations()) { if (bd instanceof FieldDeclaration) { apply((ASTNode) bd); } } } private ListsuperClasses(AbstractTypeDeclaration atd) { if (atd instanceof TypeDeclaration) { return AstUtils.superClasses((TypeDeclaration) atd); } else { return Collections.EMPTY_LIST; } } }
它依賴的AstUtils, FindUpper, SourcePathCollector設施都在Exia里面,配合使用即可。https://github.com/sorra/exia
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64351.html
摘要:前情提要深入理解內存模型四鎖的釋放獲取建立的關系鎖是并發編程中最重要的同步機制。鎖內存語義的實現本文將借助的源代碼,來分析鎖內存語義的具體實現機制。請看下篇深入理解內存模型六 前情提要 深入理解Java內存模型(四)—— volatile 鎖的釋放-獲取建立的happens before 關系 鎖是java并發編程中最重要的同步機制。鎖除了讓臨界區互斥執行外,還可以讓釋放鎖的線程向...
摘要:網站信息頁面需求分析我們公司的需要一個對外宣傳的網站介紹介紹公司的主要業務公司的發展歷史公司的口號等等信息技術分析概述超文本標記語言超文本比普通文本功能更加強大可以添加各種樣式標記語言通過一組標簽來對內容進行描述關鍵字是由瀏覽器來解釋執行靜 1.網站信息頁面 1.1需求分析: 我們公司的需要一個對外宣傳的網站介紹,介紹公司的主要業務,公司的發展歷史,公司的口號等等信息 1.2技術分析:...
摘要:一言以蔽之,被修飾的變量能夠保證每個線程能夠獲取該變量的最新值,從而避免出現數據臟讀的現象。為了實現內存語義時,編譯器在生成字節碼時,會在指令序列中插入內存屏障來禁止特定類型的處理器重排序。volatile原理volatile簡介Java內存模型告訴我們,各個線程會將共享變量從主內存中拷貝到工作內存,然后執行引擎會基于工作內存中的數據進行操作處理。 線程在工作內存進行操作后何時會寫到主內存中...
摘要:一言以蔽之,被修飾的變量能夠保證每個線程能夠獲取該變量的最新值,從而避免出現數據臟讀的現象。為了實現內存語義時,編譯器在生成字節碼時,會在指令序列中插入內存屏障來禁止特定類型的處理器重排序。volatile原理volatile簡介Java內存模型告訴我們,各個線程會將共享變量從主內存中拷貝到工作內存,然后執行引擎會基于工作內存中的數據進行操作處理。 線程在工作內存進行操作后何時會寫到主內存中...
閱讀 3106·2021-11-18 10:02
閱讀 2618·2021-10-13 09:47
閱讀 3034·2021-09-22 15:07
閱讀 791·2019-08-30 15:43
閱讀 1810·2019-08-30 10:59
閱讀 1685·2019-08-29 15:34
閱讀 1703·2019-08-29 15:06
閱讀 439·2019-08-29 13:28