【IDEA插件开发】Quick Fix 快速修复插件开发
文章目录
- 前言
- 一、Quick Fix是什么?
- 二、开发quick fix 通常包含两部分
- 1. Annotator
- 2.quick fix
- 3. FixAnnotationEnum
- 4、注册插件
- 三、演示
- 总结
前言
以下代码为开发idea quick fix功能插件演示代码,该代码实现的功能是:对于标注有SpingMVC中的 GetMapping
、PostMapping
、PatchMapping
、PutMapping
、DeleteMapping
和RequestMapping
等注解等方法,若没有同时标注LevenApi
注解,则在方法名上会出现警告,提示开发者加上LevenApi
注解,此时使用quick fix的功能即可在方法上生成LevenApi
注解。
一、Quick Fix是什么?
quick fix就是快速修复的意思,在idea编辑代码的时候,当我们输入一些违法或者是不安全(或是不推荐)的代码时,idea会自动帮我们检测出来,并使用红色或黄色波浪线提示我们修改代码。对于有些非法或者是不推荐的代码,idea能够推测出正确或者是被推荐的代码时,就会给我们提供一个快速修复的功能,这个功能就是quick fix。
而前面的检测行为则是由Annotator功能完成的,因此quick fix通常是跟着Annotator出现的,而有Annotator却不一定有quick fix(就是没有推荐修改的情况)。
以上图片演示就是常见的quick fix场景——导入类。红色方块就是Annotator,提示“无法解析BigDecimal”;橙色框则是quick fix,通过点击Import class
或者使用快捷键(Windows是alt + enter
,Mac是option + enter
)快速导入BigDecimal类。
二、开发quick fix 通常包含两部分
1. Annotator
筛选出需要quick fix的代码段:校验标注有SpringMVC mapping相关注解的方法是否同时标注有@LevenApi
注解,如果没有则在这个方法名上添加Annotator
,提示需要加上@LevenApi
注解
package run.leven.fix;import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;/*** Create By leven [2021/12/21 9:34 下午]*/
public class LevenApiAnnotator implements Annotator {private static final Set<String> MAPPING_NAME_SET;static {MAPPING_NAME_SET = new HashSet<>(Arrays.asList(FixAnnotationEnum.PatchMapping.getQualifiedName(),FixAnnotationEnum.PutMapping.getQualifiedName(),FixAnnotationEnum.PostMapping.getQualifiedName(),FixAnnotationEnum.GetMapping.getQualifiedName(),FixAnnotationEnum.RequestMapping.getQualifiedName(),FixAnnotationEnum.DeleteMapping.getQualifiedName()));}@Overridepublic void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {final Project project = element.getProject();// 项目或者引入的依赖包含LevenApi时才处理if (JavaPsiFacade.getInstance(project).findClass(FixAnnotationEnum.LevenApi.getQualifiedName(), GlobalSearchScope.allScope(project)) == null){return;}// 仅对Java方法处理if (!(element instanceof PsiMethod)){return;}// 仅对Java文件处理if (!(element.getContainingFile() instanceof PsiJavaFile)){return;}final PsiMethod psiMethod = (PsiMethod) element;final PsiAnnotation[] methodAnnotations = psiMethod.getAnnotations();PsiAnnotation mappingAnnotation = null;PsiAnnotation levenApiAnnotation = null;for (PsiAnnotation methodAnnotation : methodAnnotations) {if (MAPPING_NAME_SET.contains(methodAnnotation.getQualifiedName())){mappingAnnotation = methodAnnotation;}else if (FixAnnotationEnum.LevenApi.getQualifiedName().equals(methodAnnotation.getQualifiedName())){levenApiAnnotation = methodAnnotation;}}// 方法上标注了spring mvc相关的mapping注解时,如果同时不存在@LevenApi注解,则quick fix生效if (mappingAnnotation != null && levenApiAnnotation == null && psiMethod.getNameIdentifier() != null){holder.newAnnotation(HighlightSeverity.WARNING, "添加@LevenApi注解").range(psiMethod.getNameIdentifier()).highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).withFix(new LevenApiQuickFix(psiMethod)).create();}}
}
2.quick fix
quick fix处理:在方法上创建@LevenApi
注解
package run.leven.fix;import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;/*** Create By leven [2021/12/21 10:30 下午]*/
public class LevenApiQuickFix extends BaseIntentionAction {private final PsiMethod psiMethod;public LevenApiQuickFix(PsiMethod psiMethod) {this.psiMethod = psiMethod;}@Overridepublic @IntentionName @NotNull String getText() {return "Create @LevenApi";}@Overridepublic @NotNull @IntentionFamilyName String getFamilyName() {return "Create @LevenApi";}@Overridepublic boolean isAvailable(@NotNull Project project, Editor editor, PsiFile psiFile) {return true;}@Overridepublic void invoke(@NotNull Project project, Editor editor, PsiFile psiFile) throws IncorrectOperationException {// GlobalSearchScope.projectScope(project) 为allScopefinal PsiClass levenApiClass = JavaPsiFacade.getInstance(project).findClass(FixAnnotationEnum.LevenApi.getQualifiedName(), GlobalSearchScope.projectScope(project));if (levenApiClass != null){ApplicationManager.getApplication().invokeLater(() -> WriteCommandAction.runWriteCommandAction(project, () ->{final PsiClass containingClass = psiMethod.getContainingClass();if (containingClass == null){return;}final PsiImportList importList = ((PsiJavaFile) containingClass.getContainingFile()).getImportList();if (importList == null){return;}importLevenApiClass(project, levenApiClass, importList);psiMethod.getModifierList().addAnnotation("LevenApi(name = \"" + psiMethod.getName() + "\")");}));}}private void importLevenApiClass(@NotNull Project project, PsiClass levenApiClass, PsiImportList importList) {boolean notExistLevenApiImportStatement = true;for (PsiImportStatement importStatement : importList.getImportStatements()) {if (FixAnnotationEnum.LevenApi.getQualifiedName().equals(importStatement.getQualifiedName())){notExistLevenApiImportStatement = false;}}if (notExistLevenApiImportStatement){final PsiImportStatement levenApiImportStatement = JavaPsiFacade.getElementFactory(project).createImportStatement(levenApiClass);importList.add(levenApiImportStatement);}}
}
3. FixAnnotationEnum
package run.leven.fix;/*** Create By leven [2021/12/21 9:37 下午]*/
public enum FixAnnotationEnum {GetMapping("GetMapping", "org.springframework.web.bind.annotation.GetMapping"),PostMapping("PostMapping", "org.springframework.web.bind.annotation.PostMapping"),PutMapping("PutMapping", "org.springframework.web.bind.annotation.PutMapping"),PatchMapping("PatchMapping", "org.springframework.web.bind.annotation.PatchMapping"),RequestMapping("RequestMapping", "org.springframework.web.bind.annotation.RequestMapping"),DeleteMapping("DeleteMapping", "org.springframework.web.bind.annotation.DeleteMapping"),LevenApi("LevenApi", "run.leven.fix.LevenApi");FixAnnotationEnum(String shortName, String qualifiedName) {this.shortName = shortName;this.qualifiedName = qualifiedName;}private String shortName;private String qualifiedName;public String getShortName() {return shortName;}public String getQualifiedName() {return qualifiedName;}
}
4、注册插件
在plugin.xml文件的extensions
标签下添加如下annotator
标签。这里的language
属性指的是自己的定义Annotator
对什么语言生效,如果想对xml文件生效,则可以把language="JAVA"
修改为language="XML"
。
<extensions defaultExtensionNs="com.intellij"><annotator language="JAVA" implementationClass="run.leven.fix.LevenApiAnnotator"/></extensions>
三、演示
如上图,加有@GetMapping
注解的方法上没有@LevenApi
注解,此时方法名上有红色波浪线,且提示“添加@LevenApi注解”。当点击“Create @LevenApi”时,会在这个方法上生成@LevenApi(value = "hello")
,如下图:
总结
【IDEA插件开发】Quick Fix 快速修复插件开发相关推荐
- 捷径和妙方quick fix and silver bullet
3月24日美国总统奥巴马在白宫的新闻发布会上发表讲话时表示,政府已制定综合经济战略,美国将开始看到进展的迹象,但需要时间和耐心.在回应3.55万亿美元预算遭国会质疑时,奥巴马表示该预算与美国经济复苏是 ...
- java怎么设置快速修复键_Java开发环境之------MyEclipse快捷键和排除错误第一选择ctrl+1(***重点***:ctrl+1,快速修复---有点像vs中的快速using...
[摘要:1,MyEclipse快速键设置装备摆设方式 2,经常使用快速键 : (1),alt+/ //内容提醒, 近似于vs中的ctrl+j ,即单词提醒,输进单词的前几个字母,然后提醒大概的单词. ...
- 数仓备机DN重建:快速修复你的数仓DN单点故障
摘要:大规模分布式系统中的故障无法避免.当DN发生单点故障时,恢复手段有哪些,又是如何恢复的,本节重点介绍操作gs_ctl build是如何修复DN单点故障的. 本文分享自华为云社区<华为云数仓 ...
- 苹果充电线android头断了,【黑科技数据线!断了都能用!】 苹果安卓数据线 快速修复永不断线...
原标题:[黑科技数据线!断了都能用!] 苹果安卓数据线 快速修复永不断线 这个世界上最爽的事情是什么呢? 是躺在床上玩手机 那么最痛苦的事情是什么呢 玩到手机没电的时候数据线坏了! 这说到数据线有什么 ...
- 快速修复 bug 的技巧?初学者的痛点,教你一招搞定!
前言 写 bug 和改 bug 是每个程序员都绕不过的话题,在编写代码的过程中,相信大家肯定遇到过这种情况:代码编译通过,没有语法错误,但是运行结果却报错或和预期不同,反复检查了很多遍,仍然无法修复错 ...
- mysql的check出错_如何利用myisamchk和mysqlcheck快速修复损坏的MySQL数据库
如何利用myisamchk和mysqlcheck快速修复损坏的MySQL数据库 由于服务器的数据库硬盘空间满了,由于大量写入数据失败导致了出现"Duplicate entry '' for ...
- 彻底关闭win10更新自动更新 卸载win10自带杀毒软件 新增联想软件 lenovo quick fix
联想 lenovo quick fix 下载地址 https://box.lenovo.com/l/t5dQKH 1.开始 运行 输入services.msc. 2.找到windows update, ...
- 快速修复IE浏览器方案
快速修复浏览器方案(请活学活用以下方法--根据具体情况决定做哪些) 1.打开浏览器,点"工具"→"管理加载项"那里禁用所有可疑插件,或者你能准确知道没问题的保留 ...
- HD Tune结合硬盘再生器HDDREG快速修复硬盘错误
最近用HD Tune检查硬盘状态,结果显示(C5) 当前待映射扇区数显示黄色的警告状态 赶紧对硬盘做了备份,果然出现了某几个文件损坏读取失败的情况. 网上查了资料,发现HDDREG可以修复硬盘,但实际 ...
最新文章
- 论文小综 | 知识图谱中的复杂查询问答
- 莫比乌斯带catia建模_独家教程 | 循环曲面“莫比乌斯”,康石石教你Rhino“3步”快速打造...
- 【高并发】JUC中原子类介绍
- 拿什么来拯救你,电视!
- 自定义办法设置 localStorage 过期时间
- 数据库原理与应用 基于SQL Server 2005pdf
- 关于ipcam的UPnP或NAT的知识
- golang xorm cmd xorm工具使用 reverse 反转一个数据库结构,生成代码
- 地图 显示 动态轨迹_野外探路必备神器——奥维互动地图浏览器
- 9种常见的反爬虫策略思路
- 论文解读:MOEA/D-TPN
- Mysql性能优化:什么是索引下推?
- 19 枚举类型 Enumerated
- 【阿里巴巴/腾旭】mysql面试题汇总
- 深度学习之epoch
- C语言-第8章-基本数据类型-v2
- WiFi_combo模组功耗数据
- pycocotools报错 if type(resFile) == str or type(resFile) == unicode: NameError: name ‘unicode‘ is
- Python的IDEL增加清屏功能
- 转ios icon及默认图片等