java編譯器原始碼解析-語義分析-填充符號表
阿新 • • 發佈:2022-04-15
一、生成符號表
填充符號表的核心邏輯在com.sun.tools.javac.comp.Enter類。
在討論填充符號表的邏輯之前,首先要明確一下,什麼是符號?
我們在java程式碼中,可能會宣告一個類,類中有屬性和方法,這些對於計算機而言,都是一種符號。
在java編譯器的實現中,定義了專門的符號類Symbol及相關的子類
符號有名稱,就是我們理解的類名、方法名和屬性名。
除此之外,符號還有型別,java專門設計了一套符號型別系統來標識它。
我們舉個例子
int a=0;
我們知道,a是一個變數,但編譯器認為a是一個VarSymbol,它的型別是JCPrimitiveType.
在執行程式的時候,原生型別和引用型別有不同的處理方式。
原生型別可能存放在常量池中,但引用型別必須存在堆中,所以在編譯器在編譯期間就需要標識起來。
填充符號表分為兩個階段:
第一:類符號填充Enter
主方法為complete()所有類都進入其作用域,在visit類宣告的時候,給相關的JCClassDecl節點的sym型別定義了一個ClassSymbol的值。
類符號填充完成後,進入第二階段,呼叫enterMember.complete方法
第二:其他成員符號填充
邏輯在MemberEnter類的complete方法中
MemberEnter.visitMethodDef()給方法宣告節點的符號表填充符號。
MemberEnter.visitVarDef()給變數宣告節點的符號表填充符號。
第三:其他的符號填充在後續階段完成
生成符號的同時,符號的作用域也被識別了出來。