详解基于IDEA2020.1的JAVA代码提示插件开发例子

之前因为项目组有自己的代码规范,为了约束平时的开发规范,于是基于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文件,内容如下:

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'
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
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文件有点不一样,具体不一样的地方如下:

// See https://github.com/JetBrains/gradle-intellij-plugin/
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文件内容如下:

<idea-plugin>
  <id>org.example.new-plugin-for-java</id>
  <name>Plugin display name here</name>
  <vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>

  <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的版本的话,运行的时候会疯狂报错,一开始不知道为什么,只能又去翻官方的例子,玩大家一起来找不同,结果发现官网的例子,下面的配置信息和默认构建的不一样:

 <!-- 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 include com.intellij.modules.java

Syntax for 2019.2 and later releases:

  • plugin.xml allowable alternative include com.intellij.java
  • build.gradle required to include intellij.plugins 'java'

大概意思是,从2019.2版本开始后,java代码相关的支持抽成了一个插件,不包含在默认构建的包里面了,所以从2019.2版本开始后,plugin.xmlbuild.gradle需要修改成相关的配置。这也是为什么我们第二步要改build.gradle的原因。

4、参考网上的例子,编写第一个代码提示插件

新建一个java类,内容如下,这是一个测试用的提示插件,在所有变量上面提示"this is error"

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 nightwind666@163.com
 */
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添加上面编写的插件,如下;

 <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可以对代码进行解析等,还有PsiClassUtilPsiFieldUtil等各种相关性的工具类可以提供各种便捷的操作,这就需要插件开发者自己去摸索。遇到问题可以去IDEA官方问答论坛去找一下,说不定别人已经帮你解决了这个问题了。

附加:

IntelliJ Platform SDK官网

https://www.jetbrains.org/intellij/sdk/docs/intro/welcome.html

IntelliJ 插件开发交流社区

https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979-IntelliJ-IDEA-Open-API-and-Plugin-Development

到此这篇关于详解基于IDEA2020.1的JAVA代码提示插件开发例子的文章就介绍到这了,更多相关IDEA2020.1 JAVA代码提示插件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • IntelliJ IDEA 设置代码提示或自动补全的快捷键功能

    对于中国的Java开发者来说,可能使用Eclipse的人最多. 使用Idea的程序员也不少, 而且每个人都在鼓吹其好用之处. 试用半个月,感觉各有千秋,关键看熟练程度和配置是否好用. 自动提示快捷键 有时候希望使用自动补全,因为不偷懒的程序员不是好程序员.但是Idea的默认快捷键是 Ctrl + 空格. 对于安装中文输入法的普通人来说那就是杯具了,你懂的. 修改方法如下: 点击 文件菜单(File) –> 点击 设置(Settings- Ctrl+Alt+S), –> 打开设置对话框. 在左侧

  • 解决IDEA JSP没有代码提示问题的几种方法

    几天前遇到这样的问题,输入request.的时候按理说应该有一些getParameter等提示,我却没有,从头到尾都是死记硬背,简直不要太难受. 大概就是上图这B样,提示的都是写什么??咩咩咩?? 网上查了很多方法,都不行.今天无意中解决,所以分享出来希望大家不要再在此处栽跟头,浪费时间. 为了能帮助更多人解决问题,就把各种导致没有提示的情况一一列举. 1.省电mode问题. IDEA这东西你不小心开了省电模式,就真的毫不留情. 解决方法: File -> Power save mode 要看注

  • 详解基于IDEA2020.1的JAVA代码提示插件开发例子

    之前因为项目组有自己的代码规范,为了约束平时的开发规范,于是基于2019.1.3版本开发了一个代码提示的插件.但是在把IDEA切换到2020.1版本的时候,却发现疯狂报错,但是网上关于IDEA插件开发的相关文章还是不够多,只能自己解决.于是根据官方的SDK文档,使用Gradle重新构建了一下项目,把代码拉了过来.下文会根据2020.1版本简单开发一个代码异常的提示插件,把容易踩坑的地方提示一下. 1.首先先根据IDEA插件开发官方文档,用Gradle新建一个project 选中file -> n

  • Spring学习笔记1之IOC详解尽量使用注解以及java代码

    在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目. 预想的基本流程如下: 1.用户网站注册,填写用户名.密码.email.手机号信息,后台存入数据库后返回ok.(学习IOC,mybatis,SpringMVC的基础知识,表单数据验证,文件上传等) 2.服务器异步发送邮件给注册用户.(学习消息队列) 3.用户登录.(学习缓存.Spring Security) 4.其他. 边学习边总结,不定时更新.项目环境为Intellij + Spring4. 一.准备工作. 1.m

  • Java 添加、删除、格式化Word中的图片步骤详解( 基于Spire.Cloud.SDK for Java )

    本文介绍使用Spire.Cloud.SDK for Java提供的ImagesApi接口来操作Word中的图片.具体可通过addImage()方法添加图片.deleteImage()方法删除图片.updateImageFormat()格式化Word中的图片以及getImageFormat()获取Word中的图片格式等.操作方法和代码示例可参考下文中的步骤. 步骤1:导入jar文件 创建Maven项目程序,通过maven仓库下载导入.以IDEA为例,新建Maven项目,在pom.xml文件中配置m

  • 详解IntelliJ IDEA2020.1和JDK14体验

    IntelliJ IDEA2020.1和JDK14体验 IntelliJ IDEA新功能: 界面支持中文 但这里要注意的是不是原生支持中文,而是要安装jetbrains的官方插件,如下图 导航栏改进 上面的导航栏可以直接跳转到各个方法,这个以前要实现的话要点左侧的Structure,现在就方便多了 支持Javadoc的渲染 以前Javadoc看起来很费劲,要手动转换html格式,现在看起来就很方便了,还可以更改字体大小 以前 现在 新增主题和字体 主题: 字体: Lightedit模式 你可以把

  • 详解基于Android的Appium+Python自动化脚本编写

    1.Appium Appium是一个开源测试自动化框架,可用于原生,混合和移动Web应用程序测试, 它使用WebDriver协议驱动iOS,Android和Windows应用程序. 通过Appium,我们可以模拟点击和屏幕的滑动,可以获取元素的id和classname,还可以根据操作生成相关的脚本代码. 下面开始Appium的配置. appPackage和APPActivity的获取 任意下载一个app 解压 但是解压出来的xml文件可能是乱码,所以我们需要反编译文件. 逆向AndroidMan

  • Struts2单选按钮详解及枚举类型的转换代码示例

    本文研究的主要是Struts2框架单选按钮详解及枚举类型的转换的相关示例,具体如下. 使用struts2标签,毫无疑问要先引入标签库: <%@ taglib prefix="s" uri="/struts-tags"%> 假设radio单选框中List的值为一个Map集合: <s:radio list="#{'MAN':'男','WOMEN':'女'}" name="gender" listKey="

  • zabbix 4.04 安装文档教程详解(基于CentOS 7.6)

    1    安装前准备: 1.1   安装JDK 卸载openjdk # rpm -qa | grep java # yum remove java-1.8.0-openjdk # yum remove java-1.8.0-openjdk-headless 安装JDK包 # rpm -ivh jdk-8u191-linux-x64.rpm 1.2   安装依赖包 # yum install -y net-snmp net-snmp-devel OpenIPMI-devel libssh2-dev

  • 详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程

    一.导入excel文件和相关库 import pandas; import matplotlib; from pandas.tools.plotting import scatter_matrix; data = pandas.read_csv("D:\\面积距离车站.csv",engine='python',encoding='utf-8') 显示文件大小 data.shape data 二.绘制多个变量两两之间的散点图:scatter_matrix()方法 #绘制多个变量两两之间的

  • 详解基于Spring Data的领域事件发布

    领域事件发布是一个领域对象为了让其它对象知道自己已经处理完成某个操作时发出的一个通知,事件发布力求从代码层面让自身对象与外部对象解耦,并减少技术代码入侵. 一. 手动发布事件 // 实体定义 @Entity public class Department implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer departmentId; @Enumerate

  • 详解基于python的全局与局部序列比对的实现(DNA)

    程序能实现什么 a.完成gap值的自定义输入以及两条需比对序列的输入 b.完成得分矩阵的计算及输出 c.输出序列比对结果 d.使用matplotlib对得分矩阵路径的绘制 一.实现步骤 1.用户输入步骤 a.输入自定义的gap值 b.输入需要比对的碱基序列1(A,T,C,G)换行表示输入完成 b.输入需要比对的碱基序列2(A,T,C,G)换行表示输入完成 输入(示例): 2.代码实现步骤 1.获取到用户输入的gap,s以及t 2.调用构建得分矩阵函数,得到得分矩阵以及方向矩阵 3.将得到的得分矩

随机推荐