之前因為項目組有自己的代碼規范,為了約束平時的開發規范,于是基于2019.1.3版本開發了一個代碼提示的插件。但是在把IDEA切換到2020.1版本的時候,卻發現瘋狂報錯,但是網上關于IDEA插件開發的相關文章還是不夠多,只能自己解決。于是根據官方的SDK文檔,使用Gradle重新構建了一下項目,把代碼拉了過來。下文會根據2020.1版本簡單開發一個代碼異常的提示插件,把容易踩坑的地方提示一下。
1、首先先根據IDEA插件開發官方文檔,用Gradle新建一個project
選中file -> new -> Project...
,在彈出的窗口左側選擇Gradle
,彈出以下界面:
默認勾選了Java,需要額外勾選IntelliJ Platform Plugin
來表示這是一個IDEA插件項目,還需要勾選Kotlin/JVM
這一項,為什么要勾選這一項呢,官網是這么介紹的:
To include support for the Kotlin language in the plugin, check the Kotlin/JVM box (circled in green below.) This option can be selected with or without the Java language.
也就是說,如果我們開發的插件需要對JAVA代碼做支持的話,是要勾選這一項的。所有如果插件是基于JAVA代碼檢查的話,需要勾選這一個選項。
勾選完之后,點擊next,之后的信息根據自己實際需要填寫即可,然后點擊finish,然后默默等待Gradle構建項目,如果可以的話掛個梯子,下載包什么的還是挺慢的。
構建完后的項目的目錄結構以及每一個目錄的作用,可以直接去看官方文檔,里面有介紹。
https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.html
2、 構建完項目后,需要修改build.gradle部分配制
構建完后,默認會打開build.gradle
文件,內容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
plugins { id 'java' id 'org.jetbrains.intellij' version '0.4.19' id 'org.jetbrains.kotlin.jvm' version '1.3.71' } group 'org.example' version '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" testCompile group: 'junit', name: 'junit', version: '4.12' } intellij { version '2020.1' } compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } patchPluginXml { changeNotes """ Add change notes here.<br> <em>most HTML tags may be used</em>""" } |
這里有個坑,構建完后,我把以前的代碼復制過來,提醒我有部分類沒有找到,也就是說沒有引入對應的jar包。后來我在官網例子里面發現,它的build.gradle
文件,和我的build文件有點不一樣,具體不一樣的地方如下:
1
2
3
4
5
6
|
intellij { version = '2020.1' plugins = ['java'] sameSinceUntilBuild = true } |
它在intellij里面,多了一個plugins = ['java']
的選項,如果缺少這個選項的話,會缺少java-api.jar
等jar等JAVA代碼支持的jar包,導致一些類或者方法不可用。所以如果是JAVA代碼支持的話,build.gradle
文件需要加上plugins = ['java']
這一行。
3、修改plugin.xml文件
plugin.xml
文件是對于本插件的作用的一些描述,以及一些依賴關系配制,構建完后的plugin.xml
文件內容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
< idea-plugin > < id >org.example.new-plugin-for-java</ id > < name >Plugin display name here</ name > < description > <![CDATA[ Enter short description for your plugin here.<br> <em>most HTML tags may be used</em> ]]> </ description > <!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html on how to target different products --> < depends >com.intellij.java</ depends > < extensions defaultExtensionNs = "com.intellij" > <!-- Add your extensions here --> < localInspection language = "JAVA" displayName = "test displayer" groupPath = "Java" groupBundle = "messages.InspectionsBundle" groupKey = "group.names.probable.bugs" enabledByDefault = "true" level = "ERROR" implementationClass = "com.nw.TestInsepction" /> </ extensions > < actions > <!-- Add your actions here --> </ actions > </ idea-plugin > |
這里有個坑,如果是IDEA2019.2以前的版本的話,這個文件不用其他東西,直接參考網上的插件開發教程,寫好代碼,就可以正常運行了。但是如果是IDEA2019.2的版本的話,運行的時候會瘋狂報錯,一開始不知道為什么,只能又去翻官方的例子,玩大家一起來找不同,結果發現官網的例子,下面的配置信息和默認構建的不一樣:
1
2
|
<!-- Evaluates java PSI --> < depends >com.intellij.modules.java</ depends > |
原來這里的依賴還要改一下,改成上面這樣,那為什么要改成這個依賴呢,這個時候,我才發現默認構建的plugin.xml
里面,在depends上面有一段注釋,大概意思就是,請前往注釋里面的網站去找到如何根據產品去選擇對應的depends,那就很簡單了,直接上網頁看,里面很多的介紹,以及各種不同的depends是干嘛的。網頁里面有這么一段話:
(2) The Java language functionality was extracted as a plugin in version 2019.2 of the IntelliJ Platform. This refactoring separated the Java implementation from the other, non-language portions of the platform. Consequently, Java dependencies are expressed differently in plugin.xml
depending on the version of the IntelliJ Platform being targeted:
Syntax required for releases prior to 2019.2, allowable in all releases:
-
plugin.xml
includecom.intellij.modules.java
Syntax for 2019.2 and later releases:
-
plugin.xml
allowable alternative includecom.intellij.java
-
build.gradle
required to includeintellij.plugins 'java'
大概意思是,從2019.2版本開始后,java代碼相關的支持抽成了一個插件,不包含在默認構建的包里面了,所以從2019.2版本開始后,plugin.xml
和build.gradle
需要修改成相關的配置。這也是為什么我們第二步要改build.gradle
的原因。
4、參考網上的例子,編寫第一個代碼提示插件
新建一個java類,內容如下,這是一個測試用的提示插件,在所有變量上面提示"this is error"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com; import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiField; import org.jetbrains.annotations.NotNull; /** * 這是一個測試用的提示插件,在所有變量上面提示"this is an error" * @author LiuYeFeng * @date 2020/5/5 * @e-mail [email protected] */ public class TestInspectionTool extends AbstractBaseJavaLocalInspectionTool { @NotNull @Override public PsiElementVisitor buildVisitor( @NotNull ProblemsHolder holder, boolean isOnTheFly) { // 返回一個java元素的訪問器,重寫當訪問變量的時候,需要做的操作 return new JavaElementVisitor() { @Override public void visitField(PsiField field) { super .visitField(field); // 注冊問題,也就是在變量上面顯示異常紅色下劃線,并提示"this is an error" // 如果可以的話,這里也可以附帶上快速修復問題的方法 holder.registerProblem(field, "this is an error" ); } }; } } |
然后在plugin.xml
里面的extensions
添加上面編寫的插件,如下;
1
2
3
4
5
6
7
8
9
10
11
12
|
< extensions defaultExtensionNs = "com.intellij" > <!-- Add your extensions here --> < localInspection language = "JAVA" displayName = "Test field error" groupPath = "Java" groupBundle = "messages.InspectionsBundle" groupKey = "group.names.probable.bugs" enabledByDefault = "true" level = "ERROR" implementationClass = "com.TestInspectionTool" /> </ extensions > |
以上配置大致是注冊一個代碼提示組件,里面的參數會決定你的提示配置在IDEA的哪個分類里面,以及提示的等級,例子里面用ERROR級別,可以查看的簡單一點。
5、開始看代碼提示插件的效果
點擊右上角的debug,等待編譯運行。運行后會彈出一個新的IDEA,這個IDEA會加載了我們編寫的插件,同時在我們原來編寫插件的IDEA可以看到日志輸出等東西,也可以斷點。可以簡單理解為新的IDEA是一個瀏覽器,我們在用網頁調試后端接口。
因為我們編寫的插件是新寫一個變量,不管三七二十一就會報錯,提示this is an error
,效果如下;
到此,一個完成的代碼異常提示插件,就簡單完成了。
6、代碼提示插件還可以做到的
我們編寫的這個插件,其實是比較簡單的,并沒有做邏輯分析。我們是可以根據實際需要,去編寫一些項目組本身特有的功能的,例如某些繼承自特殊類的所有字段,必須要有注釋。在Service里面的方法,異常返回之前必須要記錄日志或者一些其他操作等,都是可以做到的,還可以做一些快速修復(quick fix),例如字段沒有注釋可以快速生成注釋。
這就需要對IDEA語法樹相關有了解,IDEA把代碼抽象成了Psi語法樹,根據不同的代碼功能劃分為不同的PsiElement
,例如注釋是PsiComment
,字段是PsiField
,方法是PsiMethod
,類是PsiClass
。IDEA本身也提供了相當多的工具類,例如ReferencesSearch
可以尋找類或者方法的引用點,PsiTreeUtil
可以處理代碼語法樹上面的一些操作,例如獲取變量所在的方法,ControlFlowUtil
可以對代碼進行解析等,還有PsiClassUtil
和PsiFieldUtil
等各種相關性的工具類可以提供各種便捷的操作,這就需要插件開發者自己去摸索。遇到問題可以去IDEA官方問答論壇去找一下,說不定別人已經幫你解決了這個問題了。
附加:
https://www.jetbrains.org/intellij/sdk/docs/intro/welcome.html
https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979-IntelliJ-IDEA-Open-API-and-Plugin-Development
到此這篇關于詳解基于IDEA2020.1的JAVA代碼提示插件開發例子的文章就介紹到這了,更多相關IDEA2020.1 JAVA代碼提示插件內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_45781803/article/details/105935826