转载

IDEA插件在研发提效上的实践(下)

背景

上一篇文章,我们介绍了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插件在研发提效上的实践(下)

此时在IDEA的目录中就能看到一个名称为FileTest.java的文件。

IDEA插件在研发提效上的实践(下)

目前只是一个空文件,因为没有导包和类定义相关的内容,所有IDEA将其认定为一个不可编译的Java文件。可以看到它和其他的Java文件相比,图标是不同的。

PsiJavaFile

如果当前PsiFile对象所指定的文件是一个Java文件,则可以将其转为PsiJavaFile对象。

IDEA插件在研发提效上的实践(下)

PsiJavaFile对象中包含了文件所在包的声明(PsiPackageStatement)、导入的包列表(PsiImportList)和文件中的类(PsiClass)等内容。如果要对java文件的内容进行修改,则可以操作PsiJavaFile对象。

现在我们创建一个包和类,把它添加到刚才创建的FileTest.java文件中。

IDEA插件在研发提效上的实践(下)

这时文件中就有了包和类的声明,IDEA也将其图标改为了Java类的图标。

IDEA插件在研发提效上的实践(下)

PsiClass

如果想对Java文件中类的内容进行操作,可以通过PsiClass对象进行。

我们可以发现一个有趣的现象,当我们把光标放到类的大括号中以及类的注释所在的行,

IDEA插件在研发提效上的实践(下)

点击右键-> Generate,就能看到很多关于类的操作。

IDEA插件在研发提效上的实践(下)

但如果把光标放到了包路径或导包所在的行,

IDEA插件在研发提效上的实践(下)

就只剩下了版权这一项操作了。

IDEA插件在研发提效上的实践(下)

类的大括号中以及类的注释所在的位置,就是一个PsiClass对象所作用的范围。

在PsiClass中,可以通过以下方式对类中的元素进行操作:

判断该类对象的类型

IDEA插件在研发提效上的实践(下)

获取该类对象的信息

IDEA插件在研发提效上的实践(下)

获取类中的元素

IDEA插件在研发提效上的实践(下)

以上只列举了部分PsiClass对象中的方法,下面我们向类中添加元素。

添加注解

给类添加SCFSerializable的注解。(注意:所有对PSI元素的写操作都需要放到WriteCommandAction的runWriteCommandAction()方法中进行)

IDEA插件在研发提效上的实践(下)

代码执行后将得到如下结果。

IDEA插件在研发提效上的实践(下)

因为没有导入注解所在的包,所有该注解会被IDEA标红报错。可以通过以下方法执行导包操作。

IDEA插件在研发提效上的实践(下)

此时就能看到导入的包,IDEA中的编译也不会报错了。

IDEA插件在研发提效上的实践(下)

PsiField

对象对类中的属性进行操作,可以通过PsiField对象进行。在PsiField中可以通过以下方法获取属性的信息。

IDEA插件在研发提效上的实践(下)

添加属性

向类中添加属性,可以通过以下的方式进行。

IDEA插件在研发提效上的实践(下)

执行后将向类中新增一个age属性。

IDEA插件在研发提效上的实践(下)

添加注解

可以通过以下方法为属性添加注解。

IDEA插件在研发提效上的实践(下)

此时将在属性上添加SCFMember注解。

IDEA插件在研发提效上的实践(下)

添加注解参数

如果注解中带有参数,则可以通过PsiAnnotation对象中的setDeclaredAttributeValue()方法为该注解添加参数。

IDEA插件在研发提效上的实践(下)

此时将在注解中添加orderId的参数。

IDEA插件在研发提效上的实践(下)

其中的PSI表达式可以通过以下的方法创建。

IDEA插件在研发提效上的实践(下)

对方法的操作可以通过PsiMethod对象进行,方式和PsiField类似,这里就不重复介绍了。

PsiType

对属性数据类型的操作,可以通过PsiType对象进行。例如属性的默认值,则可以通过PsiType来获取。

基本类型

IDEA插件在研发提效上的实践(下)

数组类型

IDEA插件在研发提效上的实践(下)

集合类型

IDEA插件在研发提效上的实践(下)

引用类型,则需要先获取引用类中的所有属性,再获取每个属性的默认值。

IDEA插件在研发提效上的实践(下)

后记

IDEA插件开发中关于PSI的内容还有很多,由于文章篇幅的限制,以上内容只列举了58EE开发中用到的部分内容。希望能在以后为大家分享更多的IDEA插件开发技术。

作者简介

周德川,工程效率团队后端开发工程师。 参与代码文化和工程效率平台建设,对devops技术有相关研究。

相关文章

▪ IDE插件在58研发提效上的实践

IDEA插件在研发提效上的实践(下)

原文  http://mp.weixin.qq.com/s?__biz=MzI1NDc5MzIxMw==&mid=2247486272&idx=1&sn=59f2e08e1ca94f75450a3f8babf668c7
正文到此结束
Loading...