背景
上一篇文章,我们介绍了IDEA插件开发的一些入门知识,本篇文件将结合EE插件的功能,为大家介绍IDEA插件开发中,PSI的使用。
什么是PSI
PSI是Program Structure Interface(程序结构接口)的缩写,官方手册上的解释为IDEA平台中的一个层,负责解析文件并创建支持平台许多功能的语法和语义代码模型。换句话说,就是你想对IDEA中项目的文件进行操作,你就得使用PSI。
PsiFile
PsiFile是文件内所有内容结构的根,所有关于文件内容的操作都是在PsiFile中进行的。
在官方的开发文档中,获取PsiFile对象的方式有5种:
1、从事件获取:
e.getData(LangDataKeys.PSI_FILE);
2、从虚拟文件中获取:
PsiManager.getInstance(project).findFile();
3、从文档获取:
PsiDocumentManager.getInstance(project).getPsiFile();
4、从文件中的元素获取:
psiElement.getContainingFile();
5、从项目中文件名获取:
FilenameIndex.getFilesByName(project, name, scope);
可以通过以下步骤,在IDEA项目中创建文件。
此时在IDEA的目录中就能看到一个名称为FileTest.java的文件。
目前只是一个空文件,因为没有导包和类定义相关的内容,所有IDEA将其认定为一个不可编译的Java文件。可以看到它和其他的Java文件相比,图标是不同的。
PsiJavaFile
如果当前PsiFile对象所指定的文件是一个Java文件,则可以将其 强 转为PsiJavaFile对象。
PsiJavaFile对象中包含了文件所在包的声明(PsiPackageStatement)、导入的包列表(PsiImportList)和文件中的类(PsiClass)等内容。如果要对java文件的内容进行修改,则可以操作PsiJavaFile对象。
现在我们创建一个包和类,把它添加到刚才创建的FileTest.java文件中。
这时文件中就有了包和类的声明,IDEA也将其图标改为了Java类的图标。
PsiClass
如果想对Java文件中类的内容进行操作,可以通过PsiClass对象进行。
我们可以发现一个有趣的现象,当我们把光标放到类的大括号中以及类的注释所在的行,
点击右键-> Generate,就能看到很多关于类的操作。
但如果把光标放到了包路径或导包所在的行,
就只剩下了版权这一项操作了。
类的大括号中以及类的注释所在的位置,就是一个PsiClass对象所作用的范围。
在PsiClass中,可以通过以下方式对类中的元素进行操作:
判断该类对象的类型
获取该类对象的信息
获取类中的元素
以上只列举了部分PsiClass对象中的方法,下面我们向类中添加元素。
添加注解
给类添加SCFSerializable的注解。(注意:所有对PSI元素的写操作都需要放到WriteCommandAction的runWriteCommandAction()方法中进行)
代码执行后将得到如下结果。
因为没有导入注解所在的包,所有该注解会被IDEA标红报错。可以通过以下方法执行导包操作。
此时就能看到导入的包,IDEA中的编译也不会报错了。
PsiField
对象对类中的属性进行操作,可以通过PsiField对象进行。在PsiField中可以通过以下方法获取属性的信息。
添加属性
向类中添加属性,可以通过以下的方式进行。
执行后将向类中新增一个age属性。
添加注解
可以通过以下方法为属性添加注解。
此时将在属性上添加SCFMember注解。
添加注解参数
如果注解中带有参数,则可以通过PsiAnnotation对象中的setDeclaredAttributeValue()方法为该注解添加参数。
此时将在注解中添加orderId的参数。
其中的PSI表达式可以通过以下的方法创建。
对方法的操作可以通过PsiMethod对象进行,方式和PsiField类似,这里就不重复介绍了。
PsiType
对属性数据类型的操作,可以通过PsiType对象进行。例如属性的默认值,则可以通过PsiType来获取。
基本类型
数组类型
集合类型
引用类型,则需要先获取引用类中的所有属性,再获取每个属性的默认值。
后记
IDEA插件开发中关于PSI的内容还有很多,由于文章篇幅的限制,以上内容只列举了58EE开发中用到的部分内容。希望能在以后为大家分享更多的IDEA插件开发技术。
作者简介
周德川,工程效率团队后端开发工程师。 参与代码文化和工程效率平台建设,对devops技术有相关研究。
相关文章
▪ IDE插件在58研发提效上的实践
原文 http://mp.weixin.qq.com/s?__biz=MzI1NDc5MzIxMw==&mid=2247486272&idx=1&sn=59f2e08e1ca94f75450a3f8babf668c7