Skip to content

Commit

Permalink
调整代码结构
Browse files Browse the repository at this point in the history
  • Loading branch information
LinuxPara authored and LinuxPara committed Nov 30, 2019
1 parent 5cdfa6e commit 33cf08d
Show file tree
Hide file tree
Showing 20 changed files with 356 additions and 240 deletions.
Binary file added .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion MVP-Plugin/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin>
<id>com.mvp.plugin</id>
<name>MVP_Plugin</name>
<version>1.2.6</version>
<version>1.2.8</version>
<vendor email="[email protected]" url="">陈占洋</vendor>

<description>一款MVP框架代码生成插件。帮助使用者管理V、P层的关系,取消V层继承框架内的类。</description>
Expand Down
124 changes: 72 additions & 52 deletions MVP-Plugin/src/com/mvp/plugin/MvpCodeAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.mvp.plugin.bean.MvpClazz;
import com.mvp.plugin.tools.PsiAnnotationTool;
import com.mvp.plugin.tools.PsiFileTool;
import com.mvp.plugin.tools.PsiTool;
import com.mvp.plugin.tools.PsiMethodTool;
import org.apache.http.util.TextUtils;

import java.util.ArrayList;
Expand All @@ -23,100 +24,119 @@ public class MvpCodeAction extends AnAction {
public static final String MVP_V_Presenters = "presenters";
public static final String MVP_Itr = "com.mvp.plugin.dependent.annotation.MVP_Itr";

public static final String MVP_DIALOG_TITLE = "Mvp-Code";

@Override
public void actionPerformed(AnActionEvent e) {
PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);

//=============================================文件必须为java文件==============================================
if (psiFile.getFileType() != StdFileTypes.JAVA) {
//获取到的文件不是java文件,则不作任何操作。
Messages.showMessageDialog("当前Mvp-Code插件操作的文件非Java文件!", "Mvp-Code", null);
Messages.showMessageDialog("当前Mvp-Code插件操作的文件非Java文件!", MVP_DIALOG_TITLE, null);
return;
}

PsiClass psiClazz = PsiTool.getPsiClazz(psiFile);
//=============================================文件中必须定义了类==============================================
PsiClass psiClazz = PsiFileTool.getPsiClazz(psiFile);
if (psiClazz == null) {
//包名为空,包名可能没内容,回去没有包名。
Messages.showMessageDialog("未在Java文件发现定义的类!", "Mvp-Code", null);
Messages.showMessageDialog("未在Java文件发现定义的类!", MVP_DIALOG_TITLE, null);
return;
}

//=============================================类必须含有@MVP_V注解==============================================
PsiAnnotation MVP_V_Ano = psiClazz.getAnnotation(MVP_V);
if (MVP_V_Ano == null) {
Messages.showMessageDialog(String.format("当前Mvp-Code插件操作的类:%s 未使用@MVP_V注解!", psiClazz.getName()), "Mvp-Code", null);
Messages.showMessageDialog(String.format("当前Mvp-Code插件操作的类:%s 未使用@MVP_V注解!", psiClazz.getName()), MVP_DIALOG_TITLE, null);
return;
}

//=============================================获取@MVP_V注解中pacakged的值==============================================
String _Mvp_V_Packaged = PsiAnnotationTool.findAnoTextValue(MVP_V_Ano, MVP_V_Packaged);
if (TextUtils.isEmpty(_Mvp_V_Packaged)) {
_Mvp_V_Packaged = PsiTool.getTextPackage(psiClazz);
_Mvp_V_Packaged = PsiFileTool.getTextPackage(psiClazz);
if (TextUtils.isEmpty(_Mvp_V_Packaged)) {
_Mvp_V_Packaged = "_generate";
} else {
_Mvp_V_Packaged += "._generate";
}
}

//=============================================获取@MVP_V注解中key的值==============================================
String _Mvp_V_Key = PsiAnnotationTool.findAnoTextValue(MVP_V_Ano, MVP_V_Key);
if (TextUtils.isEmpty(_Mvp_V_Key)) {
Messages.showMessageDialog("@MVP_V注解的属性key未指定 或 为空!", "Mvp-Code", null);
Messages.showMessageDialog("@MVP_V注解的属性key未指定 或 为空!", MVP_DIALOG_TITLE, null);
return;
}

//=============================================获取@MVP_V注解中presenters的数组==============================================
List<PsiClass> _Mvp_V_Presenters = PsiAnnotationTool.findAnoClazzArrayValue(MVP_V_Ano, MVP_V_Presenters);
if (_Mvp_V_Presenters == null || _Mvp_V_Presenters.isEmpty()) {
Messages.showMessageDialog("@MVP_V注解的属性presenters未指定 或 为空!", "Mvp-Code", null);
}

String final_Mvp_V_Packaged = _Mvp_V_Packaged;
WriteCommandAction.runWriteCommandAction(psiClazz.getProject(), () -> {
PsiDirectory javaDir = PsiFileTool.findSupDirByName(psiFile.getParent(), "java");
PsiDirectory generatedDir = PsiFileTool.createPackageDir(javaDir, final_Mvp_V_Packaged);

//===========================================view层需要抽取的接口========================================
List<PsiMethod> extractViewPsiMethods = PsiAnnotationTool.getAnoMethods(psiClazz, MVP_Itr);
if (extractViewPsiMethods == null || extractViewPsiMethods.isEmpty()) {
//=============================================获取类中被@MVP_Itr修饰的方法==============================================
List<PsiMethod> extractViewPsiMethods = PsiAnnotationTool.getAnoMethods(psiClazz, MVP_Itr);
if (extractViewPsiMethods == null || extractViewPsiMethods.isEmpty()) {
Messages.showMessageDialog(psiClazz.getName() + " 类中未找到MVP_Itr注解修饰的函数!", MVP_DIALOG_TITLE, null);
return;
}
if (PsiMethodTool.isModifierByStatic(extractViewPsiMethods)) {
Messages.showMessageDialog(psiClazz.getName() + " 类中被@MVP_Itr注解的函数不能被static修饰!", MVP_DIALOG_TITLE, null);
return;
}
//=============================================生成View接口==============================================
PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(psiClazz.getProject());
List<PsiMethod> viewItrMethods = PsiMethodTool.generateItrPsiMethods(extractViewPsiMethods, psiElementFactory);
MvpClazz viewItrClazz = new MvpClazz(_Mvp_V_Packaged + ".view", "I" + _Mvp_V_Key + "View", viewItrMethods);
PsiType viewItrType = psiElementFactory.createTypeFromText(viewItrClazz.getQName(), null);

MvpClazz mvpManagerClazz = new MvpClazz(_Mvp_V_Packaged + ".manager", _Mvp_V_Key + "MvpManager");
PsiImportStatement proxyPsiImport = psiElementFactory.createImportStatement(psiElementFactory.createTypeByFQClassName("java.lang.reflect.Proxy").resolve());
PsiImportStatement viewInvocationHandlerPsiImport = psiElementFactory.createImportStatement(psiElementFactory.createTypeByFQClassName("com.mvp.plugin.dependent.delegate.ViewDelegateInvocationHandler").resolve());
PsiImportStatement presenterInvocationHandlerPsiImport = psiElementFactory.createImportStatement(psiElementFactory.createTypeByFQClassName("com.mvp.plugin.dependent.delegate.PresenterDelegateInvocationHandler").resolve());
mvpManagerClazz.addPsiImort(proxyPsiImport);
mvpManagerClazz.addPsiImort(viewInvocationHandlerPsiImport);
mvpManagerClazz.addPsiImort(presenterInvocationHandlerPsiImport);
mvpManagerClazz.addPsiMethod(PsiMethodTool.createManagerPsiMethodView(psiElementFactory, "createViewDelegate", viewItrType));

List<MvpClazz> presenterItrClazzList = new ArrayList<>();
for (PsiClass mvp_v_presenter : _Mvp_V_Presenters) {
//===========================================P层需要抽取的接口========================================
List<PsiMethod> extractPresenterPsiMethods = PsiAnnotationTool.getAnoMethods(mvp_v_presenter, MVP_Itr);
if (extractPresenterPsiMethods == null || extractPresenterPsiMethods.isEmpty()) {
Messages.showMessageDialog(mvp_v_presenter.getName() + " 类中未找到MVP_Itr注解修饰的函数!", MVP_DIALOG_TITLE, null);
return;
}

//===========================================生成V层接口代码========================================
PsiDirectory viewGenerateDir = PsiFileTool.createDirIfNotExist(generatedDir, "view");
//生成View接口
PsiClass viewItrPsiClazz = PsiTool.createItrJavaFile(viewGenerateDir, "I" + _Mvp_V_Key + "View", extractViewPsiMethods);
if (viewItrPsiClazz == null || !viewItrPsiClazz.isValid()) {
if (PsiMethodTool.isModifierByStatic(extractPresenterPsiMethods)) {
Messages.showMessageDialog(mvp_v_presenter.getName() + "中被@MVP_Itr注解的函数不能被static修饰!", MVP_DIALOG_TITLE, null);
return;
}

//================================================================================================
PsiDirectory presenterGenerateDir = PsiFileTool.createDirIfNotExist(generatedDir, "presenter");
List<PsiMethod> createPresenterDelegateMethodList = new ArrayList<>();
List<PsiClass> presenterItrPsiClazzList = new ArrayList<>();
for (PsiClass presenterPsiClazz : _Mvp_V_Presenters) {
//===========================================presenter层需要抽取的接口========================================
List<PsiMethod> extractPresenterPsiMethods = PsiAnnotationTool.getAnoMethods(presenterPsiClazz, MVP_Itr);
if (extractPresenterPsiMethods == null || extractPresenterPsiMethods.isEmpty()) {
continue;
}
//===========================================生成P层接口代码========================================
PsiClass presenterItrPsiClazz = PsiTool.createItrJavaFile(presenterGenerateDir, "I" + presenterPsiClazz.getName(), extractPresenterPsiMethods);
if (presenterItrPsiClazz == null || !presenterItrPsiClazz.isValid()) {
continue;
}
presenterItrPsiClazzList.add(presenterItrPsiClazz);
//===========================================presenter层需要抽取的接口========================================
PsiMethod createPresenterDelegateMethod = PsiTool.createPresenterDelegateMethod(presenterPsiClazz, presenterItrPsiClazz, viewItrPsiClazz);
createPresenterDelegateMethodList.add(createPresenterDelegateMethod);

PsiTool.createConstrotMethodIfExist(presenterPsiClazz, viewItrPsiClazz, "viewDelegate");
mvpManagerClazz.addPsiImort(psiElementFactory.createImportStatement(mvp_v_presenter));
//=============================================生成Presenter接口==============================================
List<PsiMethod> presenterItrMethods = PsiMethodTool.generateItrPsiMethods(extractPresenterPsiMethods, psiElementFactory);
MvpClazz presenterItrClazz = new MvpClazz(_Mvp_V_Packaged + ".presenter", "I" + mvp_v_presenter.getName(), presenterItrMethods);
presenterItrClazzList.add(presenterItrClazz);
PsiType presenterItrType = psiElementFactory.createTypeFromText(presenterItrClazz.getQName(), null);

mvpManagerClazz.addPsiMethod(PsiMethodTool.createManagerPsiMethodPresenter(psiElementFactory, "create" + mvp_v_presenter.getName() + "Delegate", presenterItrType, viewItrType, psiElementFactory.createType(mvp_v_presenter)));

}

WriteCommandAction.runWriteCommandAction(psiClazz.getProject(), () -> {
PsiDirectory javaDir = PsiFileTool.findSupDirByName(psiFile.getParent(), "java");

PsiDirectory viewDir = PsiFileTool.createPackageDir(javaDir, viewItrClazz.getPackageName());
PsiFileTool.createJavaFile(viewDir, viewItrClazz, true);

for (MvpClazz presenterItrClazz : presenterItrClazzList) {
PsiDirectory presenterDir = PsiFileTool.createPackageDir(javaDir, presenterItrClazz.getPackageName());
PsiFileTool.createJavaFile(presenterDir, presenterItrClazz, true);
}

//===========================================创建MVPManager类========================================
PsiDirectory managerGenerateDir = PsiFileTool.createDirIfNotExist(generatedDir, "manager");
PsiClass mvpManagerClazz = PsiTool.createMvpManagerJavaFile(managerGenerateDir, _Mvp_V_Key + "MvpManager", viewItrPsiClazz, createPresenterDelegateMethodList);
if (mvpManagerClazz == null || !mvpManagerClazz.isValid()) {
return;
for (PsiClass mvp_v_presenter : _Mvp_V_Presenters) {
PsiFileTool.createControtMethodIfNotExist(mvp_v_presenter, viewItrType, "viewDelegate");
}

PsiDirectory managerDir = PsiFileTool.createPackageDir(javaDir, mvpManagerClazz.getPackageName());
PsiFileTool.createJavaFile(managerDir, mvpManagerClazz, false);
});
}
}
57 changes: 57 additions & 0 deletions MVP-Plugin/src/com/mvp/plugin/bean/MvpClazz.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.mvp.plugin.bean;

import com.intellij.psi.PsiImportStatement;
import com.intellij.psi.PsiMethod;

import java.util.ArrayList;
import java.util.List;

public class MvpClazz {

private String mPackageName;
private String mClazzName;
private List<PsiMethod> mMethods;
private List<PsiImportStatement> mImports;

public MvpClazz(String packageName, String clazzName, List<PsiMethod> methods) {
this.mPackageName = packageName;
this.mClazzName = clazzName;
this.mMethods = methods;
this.mImports = new ArrayList<>();
}

public MvpClazz(String packageName, String clazzName) {
this.mPackageName = packageName;
this.mClazzName = clazzName;
this.mMethods = new ArrayList<>();
this.mImports = new ArrayList<>();
}

public void addPsiMethod(PsiMethod method) {
mMethods.add(method);
}

public void addPsiImort(PsiImportStatement psiImport) {
mImports.add(psiImport);
}

public String getQName() {
return mPackageName + "." + mClazzName;
}

public String getPackageName() {
return mPackageName;
}

public String getName() {
return mClazzName;
}

public List<PsiMethod> getMethods(){
return mMethods;
}

public List<PsiImportStatement> getImports(){
return mImports;
}
}
27 changes: 0 additions & 27 deletions MVP-Plugin/src/com/mvp/plugin/tools/GenerateTool.java

This file was deleted.

4 changes: 0 additions & 4 deletions MVP-Plugin/src/com/mvp/plugin/tools/PsiAnnotationTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ public static String findAnoTextValue(@NotNull PsiAnnotation annotation, @NotNul
}

public static List<PsiClass> findAnoClazzArrayValue(@NotNull PsiAnnotation annotation, @NotNull String key) {
if (annotation == null || !annotation.isValid()){
return null;
}

List<PsiClass> values = new ArrayList<>();
PsiAnnotationMemberValue annotationValue = annotation.findAttributeValue(key);
for (PsiElement psiElement : annotationValue.getChildren()) {
Expand Down
61 changes: 58 additions & 3 deletions MVP-Plugin/src/com/mvp/plugin/tools/PsiFileTool.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.mvp.plugin.tools;

import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.mvp.plugin.bean.MvpClazz;
import org.apache.http.util.TextUtils;
import org.jetbrains.annotations.NotNull;

Expand All @@ -10,6 +11,24 @@
public class PsiFileTool {
private static final String JAVA_SUFFIX = ".java";

public static PsiClass getPsiClazz(@NotNull PsiFile psiFile) {
for (PsiElement psiElement : psiFile.getChildren()) {
if (psiElement instanceof PsiClass) {
return ((PsiClass) psiElement);
}
}
return null;
}

public static String getTextPackage(PsiClass psiClazz) {
String qName = psiClazz.getQualifiedName();
return qName.substring(0, qName.length() - psiClazz.getName().length() - 1);
}
// public static boolean isExist(@NotNull PsiDirectory parentDir, @NotNull String fileName) {
// PsiFile psiFile = parentDir.findFile(ensureJavaSuffix(fileName));
// return psiFile != null && psiFile.getVirtualFile().exists();
// }

public static PsiDirectory createDirIfNotExist(@NotNull PsiDirectory parentDir, @NotNull String dirName) {
PsiDirectory subDir = parentDir.findSubdirectory(dirName);
if (subDir == null || !subDir.getVirtualFile().exists()) {
Expand Down Expand Up @@ -42,7 +61,7 @@ public static PsiDirectory findSupDirByName(@NotNull PsiDirectory psiDir, @NotNu
}

public static PsiDirectory createPackageDir(@NotNull PsiDirectory psiDir, @NotNull String packageName) {
if (TextUtils.isEmpty(packageName)){
if (TextUtils.isEmpty(packageName)) {
return psiDir;
}
String[] dirs = packageName.split("\\.");
Expand All @@ -51,4 +70,40 @@ public static PsiDirectory createPackageDir(@NotNull PsiDirectory psiDir, @NotNu
}
return psiDir;
}

public static PsiClass createJavaFile(@NotNull PsiDirectory parentDir, @NotNull MvpClazz Clazz, boolean isInterface) {
PsiClass psiClazz = null;
if (isInterface) {
deleteFileIfExist(parentDir,ensureJavaSuffix(Clazz.getName()));
psiClazz = JavaDirectoryService.getInstance().createInterface(parentDir, Clazz.getName());
} else {
deleteFileIfExist(parentDir,ensureJavaSuffix(Clazz.getName()));
psiClazz = JavaDirectoryService.getInstance().createClass(parentDir, Clazz.getName());
}

for (PsiImportStatement clazzImport : Clazz.getImports()) {
((PsiJavaFile) psiClazz.getContainingFile()).getImportList().add(clazzImport);
}
for (PsiMethod psiMethod : Clazz.getMethods()) {
psiClazz.add(psiMethod);
}
CodeStyleManager.getInstance(parentDir.getProject()).reformat(psiClazz);
return psiClazz;
}

public static PsiMethod createControtMethodIfNotExist(@NotNull PsiClass targetClazz, @NotNull PsiType argType, @NotNull String argName) {
PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(targetClazz.getProject());

PsiMethod constructorPsiMethod = psiElementFactory.createConstructor(targetClazz.getName());
PsiParameter argPsi = psiElementFactory.createParameter(argName, argType);
constructorPsiMethod.getParameterList().add(argPsi);

PsiMethod _constructorPsiMethod = targetClazz.findMethodBySignature(constructorPsiMethod, true);
if (_constructorPsiMethod != null) {
return _constructorPsiMethod;
}
targetClazz.add(constructorPsiMethod);
return _constructorPsiMethod;
}

}
Loading

0 comments on commit 33cf08d

Please sign in to comment.