1.什么是PsiAugmentProvider
当用户在编辑器中输入.后,将在提示框中展示自定义的属性或者方法
2.创建PsiAugmentProvider项目
2.1 pom文件
<idea-plugin>
<id>com.wangxb.plugin.MyPlugin</id>
<name>我的插件</name>
<version>1.0</version>
<vendor email="wang5525369@sina.com" url="http://www.wangxb.com">wangxb</vendor>
<description>我的插件我的插件我的插件我的插件我的插件我的插件我的插件说明主要是增加属性的说明</description>
<change-notes>我的插件我的插件我的插件我的插件我的插件我的插件我的插件说明主要是增加属性的说明</change-notes>
<!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="193.0"/>
<!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<depends>com.intellij.modules.java</depends>
<extensions defaultExtensionNs="com.intellij">
<lang.psiAugmentProvider implementation="com.wangxb.plugin.MyPsiAugmentProvider"/>
</extensions>
<actions>
</actions>
</idea-plugin>
2.2代码文件
package com.wangxb.plugin;
import com.intellij.ide.structureView.StructureViewExtension;
import com.intellij.lang.jvm.JvmParameter;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.light.LightFieldBuilder;
import com.intellij.psi.impl.light.LightModifierList;
import com.intellij.psi.impl.light.LightParameter;
import com.intellij.psi.impl.light.LightParameterListBuilder;
import com.intellij.psi.impl.source.PsiExtensibleClass;
import com.intellij.psi.util.CachedValuesManager;
import com.wangxb.plugin.utils.MyFieldUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MyPsiAugmentProvider extends PsiAugmentProvider {
String annotaionName = "com.wangxb.annotation.AddField";
@Override
@NotNull
protected <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement psiElement, @NotNull Class<Psi> type) {
final List<Psi> emptyResult = Collections.emptyList();
if ((psiElement instanceof PsiClass) == false){
return emptyResult;
}
PsiClass psiClass = (PsiClass) psiElement;
PsiAnnotation psiAnnotation = MyFieldUtils.getAnnotation(psiClass,annotaionName);
if (psiAnnotation == null) {
return emptyResult;
}
if (PsiField.class.isAssignableFrom(type)) {
String fieldName = MyFieldUtils.getAnnotationValue(psiAnnotation, "fieldName");
if ("".equals(fieldName) == false) {
PsiType psiType = MyFieldUtils.getPsiType(psiClass,"java.lang.String");
PsiField psiField = MyFieldUtils.createCacheField(psiClass, fieldName,psiType);
List<PsiElement> psiElementList = new ArrayList<>();
psiElementList.add(psiField);
return (List<Psi>) psiElementList;
}
}else if (PsiMethod.class.isAssignableFrom(type)){
String fieldName = MyFieldUtils.getAnnotationValue(psiAnnotation, "fieldName");
String methed = MyFieldUtils.getAnnotationValue(psiAnnotation, "methed");
boolean addMethod = true;
if (StringUtils.isNotBlank(methed)) {
addMethod = new Boolean(methed);
}
if ("".equals(fieldName) == false) {
List<PsiElement> psiElementList = new ArrayList<>();
if (addMethod == true) {
PsiType psiType = MyFieldUtils.getPsiType(psiClass,"java.lang.String");
String methodName = "get" + fieldName;
//PsiType.VOID
PsiMethod psiMethod = MyFieldUtils.createCacheMethod(psiClass, methodName, null, psiType);
psiElementList.add(psiMethod);
methodName = "set" + fieldName;
List<PsiParameter> parameterList = Lists.newArrayList();
LightParameter lightParameter = new LightParameter(fieldName,psiType,psiClass);
parameterList.add(lightParameter);
psiMethod = MyFieldUtils.createCacheMethod(psiClass, methodName, parameterList, PsiType.VOID);
psiElementList.add(psiMethod);
return (List<Psi>) psiElementList;
}
}
}
return emptyResult;
}
}
package com.wangxb.plugin.utils;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightFieldBuilder;
import com.intellij.psi.impl.light.LightMethodBuilder;
import com.intellij.psi.impl.light.LightModifierList;
import com.intellij.psi.util.CachedValuesManager;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.wangxb.plugin.MyLightFieldBuilder;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import java.lang.reflect.Type;
import java.util.List;
public class MyFieldUtils {
static public void addField(PsiJavaFile psiJavaFile,String annotaionName){
PsiClass[] psiClasses = psiJavaFile.getClasses();
if (null == psiClasses) {
return;
}
for(PsiClass psiClass : psiClasses) {
PsiAnnotation psiAnnotation = psiClass.getAnnotation(annotaionName);
if (psiAnnotation == null) {
continue;
}
String fieldName = getAnnotationValue(psiAnnotation,"fieldName");
if ("".equals(fieldName) == true) {
break;
}
boolean add = haveField(psiClass,fieldName);
if (add) {
createField(psiClass,fieldName);
}
boolean method = new Boolean(getAnnotationValue(psiAnnotation,"methed"));
if (method == true){
String methodName = "get" + fieldName;
PsiType returnType = getPsiType(psiClass,"java.lang.String");
add = haveMethod(psiClass,methodName,null,returnType);
if (add) {
createMethod(psiClass,methodName,null,returnType);
}
}
break;
}
}
static public boolean haveAnnotation(PsiJavaFile psiJavaFile,String annotaionName){
boolean bRet = false;
PsiClass[] psiClasses = psiJavaFile.getClasses();
if (null == psiClasses) {
return bRet;
}
for(PsiClass psiClass : psiClasses) {
PsiAnnotation psiAnnotation = getAnnotation(psiClass,annotaionName);
if (psiAnnotation != null){
bRet = true;
break;
}
}
return bRet;
}
static public PsiAnnotation getAnnotation(PsiClass psiClass,String annotaionName){
PsiAnnotation psiAnnotation = psiClass.getAnnotation(annotaionName);
return psiAnnotation;
}
static public PsiField createField(PsiClass psiClass,String fieldName){
Project project = psiClass.getProject();
PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
PsiType stringPsiType = psiElementFactory.createTypeFromText("java.lang.String", null);
PsiField psiField = psiElementFactory.createField(fieldName, stringPsiType);
psiField.getModifierList().setModifierProperty(PsiModifier.PUBLIC,true);
WriteCommandAction.runWriteCommandAction(project, new Runnable() {
@Override
public void run() {
psiClass.add(psiField);
}
});
return psiField;
}
static public PsiField createCacheField(PsiClass psiClass,String fieldName,PsiType psiType){
PsiManager psiManager = psiClass.getContainingFile().getManager();
LightFieldBuilder lightFieldBuilder = new LightFieldBuilder(psiManager,fieldName, psiType);
LightModifierList lightModifierList = (LightModifierList) lightFieldBuilder.getModifierList();
lightModifierList.addModifier(PsiModifier.PUBLIC);
lightFieldBuilder.setContainingClass(psiClass);
return lightFieldBuilder;
}
static public String getAnnotationValue(PsiAnnotation psiAnnotation,String name){
String value = null;
PsiAnnotationParameterList psiAnnotationParameterList = psiAnnotation.getParameterList();
for (PsiNameValuePair psiNameValuePair : psiAnnotationParameterList.getAttributes()) {
String attributeName = psiNameValuePair.getAttributeName();
if (attributeName.equals(name) == false) {
continue;
}
value = psiNameValuePair.getLiteralValue();
break;
}
return value;
}
static public boolean haveField(PsiClass psiClass,String fieldName){
boolean bRet = false;
PsiField[] psiFields = psiClass.getAllFields();
PsiField lastPsiField = null;
for (PsiField psiField : psiFields) {
if (fieldName.equals(psiField.getName())) {
bRet = true;
break;
}
}
return bRet;
}
static public boolean haveMethod(PsiClass psiClass,String methodName,List<PsiParameter> parameterList,PsiType returnType){
boolean bRet = false;
PsiMethod[] psiMethods = psiClass.getAllMethods();
for (PsiMethod psiMethod : psiMethods) {
if (methodName.equals(psiMethod.getName())) {
PsiType psiType = psiMethod.getReturnType();
if (psiType.equals(returnType) == false){
return bRet;
}
PsiParameterList psiParameterList = psiMethod.getParameterList();
if (ObjectUtils.isEmpty(parameterList)){
parameterList = Lists.newArrayList();
}
if (parameterList.size() != psiParameterList.getParameters().length){
return bRet;
}
int i = 0;
for(PsiParameter parameter : parameterList){
PsiParameter psiParameter = psiParameterList.getParameter(i);
if (parameter.getName().equals(psiParameter.getName()) == false){
return bRet;
}
if (parameter.getType().equals(psiParameter.getType()) == false){
return bRet;
}
i++;
}
bRet = true;
break;
}
}
return bRet;
}
static public PsiMethod createMethod(PsiClass psiClass,String methodName,List<PsiParameter> parameterList,PsiType returnType){
Project project = psiClass.getProject();
PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
PsiMethod psiMethod = psiElementFactory.createMethod(methodName, returnType);
psiMethod.getModifierList().setModifierProperty(PsiModifier.PUBLIC,true);
WriteCommandAction.runWriteCommandAction(project, new Runnable() {
@Override
public void run() {
psiClass.add(psiMethod);
}
});
return psiMethod;
}
static public PsiMethod createCacheMethod(PsiClass psiClass,String methodName,List<PsiParameter> parameterList,PsiType returnType) {
PsiManager psiManager = psiClass.getContainingFile().getManager();
LightMethodBuilder lightMethodBuilder = new LightMethodBuilder(psiManager, JavaLanguage.INSTANCE, methodName);
lightMethodBuilder.addModifier(PsiModifier.PUBLIC);
lightMethodBuilder.setContainingClass(psiClass);
if (ObjectUtils.isNotEmpty(parameterList)) {
for (PsiParameter psiParameter : parameterList) {
lightMethodBuilder.addParameter(psiParameter.getName(), psiParameter.getType());
}
}
lightMethodBuilder.setMethodReturnType(returnType);
lightMethodBuilder.setContainingClass(psiClass);
return lightMethodBuilder;
}
static public PsiType getPsiType(PsiClass psiClass,String type){
Project project = psiClass.getProject();
PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
PsiType psiType = psiElementFactory.createTypeFromText(type, null);
return psiType;
}
}
2.3 代码效果
代码中没有abc属性
但选择是会出现abc的属性