idea中二级包为什么创建不了_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项目中创建文件。

584b8593a664aff3395b06edf9d88f85.png

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

c23f277aceea28b68c5eeb8b14f4ffb8.png

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

PsiJavaFile

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

5cf84e5ec74f34afb8c3989ae849e37b.png

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

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

86fdec222aaa3fc0b0b3e5067f8dd92e.png

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

9549390ac83a265175e8d10eab0f680d.png

PsiClass

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

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

28bc987814121425b5ee7be6d37b9433.png

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

b1e9800c6fa8d99c9d88a6fe204a61c6.png

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

cd3942bb608ac144194371e36f0974fe.png

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

53f16a6f18812a8e6c4ea6803efc5494.png

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

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

判断该类对象的类型

c789492e86ce3ff6c6fab655ff9374da.png

获取该类对象的信息

67aa5c5dce75c6470fd4275c2f38ac8f.png

获取类中的元素

5efaeeb833f612589b00f14c6cbd2b5c.png

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

添加注解

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

f5164a91694211170864d9b6ada93b65.png

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

dd857f5dc4f11c5e6abe1fba3b8dd45a.png

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

4493ad55de4c092d848caaeb08b63f29.png

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

c7f6c3e6a6f99516adbd2873e2529874.png

PsiField

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

7f2eb8993fa5ed90f9e2d94dfa1aefed.png

添加属性

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

231133b4c6c3253ac522dff06b88dd4e.png

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

d2179c8cd0463e216171d1af69d22bb6.png

添加注解

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

480d1a7d00514b53001e3457363df722.png

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

d18856d7c37a4ea3322883b12cd63adc.png

添加注解参数

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

444d3e7c50175d65f2dbade20521f4ad.png

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

93c7a93e969d8e829a1df0dea8feecaa.png

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

671cafa6e5eff847643041ea445dbc10.png

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

PsiType

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

基本类型

8304d43b13ce55c3094009053e3c7d48.png

数组类型

5f0c2e6a953c4f0cfa590f3af072677b.png

集合类型

50e9a57b70341883297ea11070868afa.png

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

886ccb25cb388208df893cf82cb58856.png

后记

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

作者简介

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

相关文章

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


欢迎大家关注“58技术”微信公众号,“58技术”是58官方技术号,58技术创新、分享与交流平台。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值