eclipseJDTeclipseast抽象语法树文档格式.docx

上传人:b****5 文档编号:19346964 上传时间:2023-01-05 格式:DOCX 页数:18 大小:249.16KB
下载 相关 举报
eclipseJDTeclipseast抽象语法树文档格式.docx_第1页
第1页 / 共18页
eclipseJDTeclipseast抽象语法树文档格式.docx_第2页
第2页 / 共18页
eclipseJDTeclipseast抽象语法树文档格式.docx_第3页
第3页 / 共18页
eclipseJDTeclipseast抽象语法树文档格式.docx_第4页
第4页 / 共18页
eclipseJDTeclipseast抽象语法树文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

eclipseJDTeclipseast抽象语法树文档格式.docx

《eclipseJDTeclipseast抽象语法树文档格式.docx》由会员分享,可在线阅读,更多相关《eclipseJDTeclipseast抽象语法树文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

eclipseJDTeclipseast抽象语法树文档格式.docx

有try,catch语句块,用JLS4,

*2,你要告诉parser需要解析的内容类型。

ASTParser支持对以下四种内容的解析:

a.K_COMPILATION_UNIT:

一个编译单元,一般就是完整的Java文件

b.K_STATEMENTS:

Javastatements,比如赋值语句,或是if语句块,while语句块等。

此类型不需要文件是完整的编译单元,但需要是完整的statements。

比如if语句块要作为一个完整的statement输入,否则会报错。

c.K_EXPRESSION:

Javaexpressions

d.K_CLASS_BODY_DECLARATIONS:

Javaclass里的元素

*3,设置java代码,java代码可以通过文件流从java文件中得到,也可以自己拼接String,记得需要的是一个char[]

*4,如果解析的内容类型的一个完整的java类,则可以不用设置,如果只是片断,则需要设定为true.

*5,需要Parser得到一个AST根对象CompilationUnit

1-2,在Util类添加一个读取java文件的方法:

publicstaticStringgetJavaFromFile(StringjavaFilePath)throwsException{

FileInputStreamreader=newFileInputStream(newFile(javaFilePath));

byte[]bs=newbyte[reader.available()];

reader.read(bs,0,reader.available());

StringjavaContent=newString(bs);

returnjavaContent;

}

2-1,ASTNode结构图

2-2,java结构说明:

2-2-1,一个java文件中:

主要包含三大块(如图):

其中包引入可以有多个,类申明也可以有多个。

当然还有注释和注解两部分:

2-2-2在类中也主要包含三大块:

全局变量(Field),方法(Method),内部类(InnerClass),另外还有:

方法注解,变量注解,方法注释,字段注释,static块,如图:

2-3,解释ASTNode

通过上面对java结构的介绍,以及2-1的图,我们可以通过

CompilationUnitunit=(CompilationUnit)parser.createAST(null);

得到ASTNode得到ast的根节点,即:

ASTNoderootNode=unit.getAST();

他表示一个java文件,或者一个完事的java片段,我们以一个完事的java文件为例,如果是一个java文件,那么,

unit相对的子节点就是多个:

package{1},import{*},class{*},javadoc{*},annotation{*},

而其中java代码主要是写类中的,所以class又有多个子节点:

field{*},constructor{*},method{*},javadoc{*},annotation{*},staticblock{*},constructor(构造方法)只是特殊的方法,所以可以归为一类,

在java中,java的表达式,逻辑主要是在method中,method中还很多了节点,即各种表达式的子节点,这个这里就不说了。

这样一来,一个java文件就够成了一棵java方法树了。

下面就开始对java结构按上面的分析出的结构逐一的分析与遍历

EclipseJDT--AST遍历

(2)JAVA结构遍历

1,遍历整个java文件:

(以附件的java内容为例),如果有不理解的地方,请仔细看上面的结构图

1-1包申明

PackageDeclarationpackageDeclaration=unit.getPackage();

得到申明的包,即:

packagexm.bean;

packageDeclaration.toString();

==>

packagexm.bean

packageDeclaration.getName();

xm.bean

1-2导入包遍历

ListimportDeclarations=unit.imports();

for(Objectobject:

importDeclarations){

ImportDeclarationimportDec=(ImportDeclaration)object;

System.out.println(importDec.getName());

//print:

java.util.List

System.out.println(importDec);

//print:

importjava.util.List

System.out.println(importDec.isOnDemand());

//print:

如果是:

importjava.util.*;

true

如果是静态导入:

importstaticjava.lang.Math.*;

true;

System.out.println(importDec.isStatic());

1-2java类遍历(在一个java文件中,如果class关键字没有public申明,则一个java文件中可以存在多个类,如果用public申明,则只有一个java类),所以TypeDeclaration得到的是一个集合:

ListtypeDeclarations=unit.types();

如果java文件中有一个类,则:

TypeDeclarationclazzNode=(TypeDeclaration)typeDeclarations.get(0);

如果有多个类,则:

for(Objectobject:

typeDeclarations){

TypeDeclarationclazzNode=(TypeDeclaration)object;

System.out.println(clazzNode.getName());

if("

Balance"

.equals(clazzNode.getName())){

//遍历类里面

}elseif(...){

...

}...

2遍历整个java类头部:

2-1,注释遍历:

java的注释分为如下三种:

a:

doc注释,这个注释可以在javadoc里面体现出来,格式:

/**

*@Description金融行业记录帐户余额信息

*一般分为:

openingbalance,coloseingbalance,availablebalence等

*@author.x.m

*@Time2013/04/22

*/

b:

块注释,与类注释不同的是:

类注释开头是:

/**而块注释是:

/*

c:

行注释//后面跟注释内容

2-2,注释遍历:

注释在AST的分析与解释

以上类注释的解释,

AST,将类注释javadoc视为由多个TagElement组成的List=javadoc.tags();

注释文件从头开始,每遇到一个@则视为一个TagElement,如上图则有4个TagElement,

而每个TagElement都是由optinonalTagName(@author)和多个TextElement,每换一次行则视为一个TextElement。

如图:

@Description这个TagElement则一个optinonalTagName(@Description)和两个TextElement组成。

2-3,注释遍历:

代码,有了如上的分析,则可以很轻松的遍历出每一行注释,当然如果没有其它的必要的话,你就可以直接javadoc.toString();

Javadocclassdoc=clazz.getJavadoc();

//得到类上面的注释javadoc

Listtargs=classdoc.tags();

//得到TagElement集合

targs){

TagElementtagElement=(TagElement)object;

StringoptionalTagName=tagElement.getTagName();

//得到注释名如:

@author

ListtextElements=tagElement.fragments();

//得到注释的内容集合:

ListTextElement

for(Objectobject2:

textElements){

TextElementtextElement=(TextElement)object2;

System.out.println(textElement.getText());

//得到一个TextElement的内容

}

2-4,java类信息:

publicclassAdapter{}//这个包含修饰符:

public,类名:

Adapter

publicabstractclassAdapter{}//这个包含修饰符:

public,abstract,类名:

Adapter

publicclassAdapterextendsAbsAdapter{}//修饰符:

public,父类:

AbsAdapter,类名:

publicclassAdapterextendsAbsAdapter<

Entity>

{}//修饰符:

Adapter,泛型:

Entity

publicclassAdapterextendsabsAdapter<

TextendsEntity>

{}

publicinterfaceAdapter{}

publicinterfaceMyAdapterextendsAdapter{}

publicinterfaceMyAdapterextendsAdapter<

publicclassAdapter<

Integer,String>

2-5:

得到各种类型信息(代码如下)

TypeDeclarationclazz=(TypeDeclaration)typeDeclarations.get

(1);

System.out.println("

ClassName:

"

+clazz.getName());

for(Objectobj:

clazz.modifiers()){//得到修辞符如:

public,static,abstract,

Modifiermodifier=(Modifier)obj;

modifier.getKeyword();

clazz.isInterface();

//是不是接口

//得到类型信息pulicclassMyAdapter<

中的<

clazz.typeParameters()){

TypeParametertypeParameter=(TypeParameter)object;

SimpleNamegenericName=typeParameter.getName();

//T

typeParameter.typeBounds()){//Entity

SimpleTypesuperGrnericType=(SimpleType)object2;

StringsuperGrnericName=superGrnericType.getName().getFullyQualifiedName();

//extendsAdapter<

TypesuperType=clazz.getSuperclassType();

System.out.println(superType);

//implementsAdapter<

BaseBean{}

ListinterfaceType=clazz.superInterfaceTypes();

for(Objectobj:

interfaceType){

ParameterizedTypeparameterizedType=(ParameterizedType)obj;

for(Objectobj1:

parameterizedType.typeArguments()){

SimpleTypesimpleType=(SimpleType)obj1;

simpleType.getName().getFullyQualifiedName();

EclipseJDT--AST遍历(3)Java类遍历

到目前已经遍历了java的大致结构了,接下来就是进行java类里面的信息进行遍历,由上面可知道,java类主要由三部分组成,这里只对这三部分来做分析(FieldDeclaration,MethodDeclaration,内部类:

TypeDeclaration),

这部分遍历有两种方式:

1,整体遍历:

因为FieldDecliaration,MethodDeclaration,TypeDeclaration都是BodyDeclaration的子类,所以可以将他们归结为同一类型的结点,于是就有:

List<

?

>

bodyDecliarations=clazz.bodyDeclarations();

然后循环得到每一个节点,如下:

clazz.bodyDeclarations()){

System.out.println(obj.getClass());

//printfield

if(objinstanceofTypeDeclaration){//innerclass

TypeDeclarationinnerClass=(TypeDeclaration)obj;

for(ObjectbodyType:

innerClass.bodyDeclarations()){

if(bodyTypeinstanceofMethodDeclaration){

MethodDeclarationinnerMethod=(MethodDeclaration)bodyType;

innerMethod.getBody();

}

}

System.out.println(innerClass.toString());

}elseif(objinstanceofFieldDeclaration){//field

}elseif(objinstanceofMethodDeclaration){//method

2:

分类遍历

2-1,字段遍历:

先分析下,字段由注释,注解,修辞符(publicstatic等),变量类型,变量名,变量值(变量值可以是常量,一个表达示,也可是调用某个类的某个方法),这里省略:

注释,注解,变量值也只针对常值的解析),其它情况在针对方法体遍历的时候说明。

下面代码片段用于字段遍历说明:

importjava.util.Date;

importjava.util.List;

publicclassFieldTest{

//基本类型

privateintintA;

//对象类型

privateDatedate;

//数组类型

privateString[]xmAccounts;

//泛型类型

privateList<

String>

xmAccountList;

//多个修辞符

publicfinalstaticdoublePI=3.141592653;

//赋空值的

privateStringxm=null;

//调用方法的

privatelongcurrentTimes=System.currentTimeMillis();

//表达式的

privatebooleanflag=100/5==20?

true:

false;

2-1-1,变量类型的说明(这里只是按ast中变量类型归类说明)

基本数据类型:

PrimitiveType,java中的基本数据类型,如:

int,float等,可以通过isPrimitiveType来判断是不是基本数据类型

复杂数据类型(对象):

SimpleType,java中的对象类型,isSimpleType断是不是对象数据类型

数组数据类型:

ArrayType,java中的数组类型

泛型数据类型:

ParameterizedType,泛型

2-1-2,由于一个类可以有多个字段申明,所以我们可以通过到getFieldDeclarations(),得到一个List数组。

然后我们通过for循环遍历这个数组,得到这个字段的相关信息,如

修辞符(private,static等)field.modifiers();

字段的类型信息:

isPrimitiveType,isSimpleType,isArrayType,isParameterizedType等方法来判断是什么类型,这样就可以得到类型名。

变量名:

注意:

一个类型可以申明多个变量:

比如:

privateinta,b,c;

所以会返回一个数组

如果只有一个变量名,我们可以直接get(0),如果多个,我们也可以遍历逐个得到。

相关代码如下:

FieldDeclaration[]fields=clazz.getFields();

for(FieldDeclarationfieldDeclaration:

fields){

Stringfield="

;

Listmodifier=fieldDeclaration.modifiers();

for(inti=0;

i<

modifier.size();

i++){

field+=modifier.get(i)+"

"

//这里得到字段类型

TypefieldType=fieldDeclaration.getType();

if(fieldType.isPrimitiveType()){

PrimitiveTypep=(PrimitiveType)fieldType;

field+=p.getPrimitiveTypeCode()+"

elseif(fieldType.isArrayType()){//数组

ArrayTypea=(ArrayType)fieldType;

field+=a.getComponentType()+"

[]"

elseif(fieldType.isSimpleType()){//对象

SimpleTypes=(SimpleType)fieldType;

field+=s.getName().getFullyQualifiedName()+"

elseif(fieldType.isParameterizedType()){//泛型,泛型,

//泛型的类型,也可能是上面两种类型,也有可能是还是泛型对象(泛型不能是基本类型)

//List<

List<

O

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 卡通动漫

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1