diff --git a/README.md b/README.md
index 4ab3a4e..d4be63d 100644
--- a/README.md
+++ b/README.md
@@ -5,10 +5,10 @@
JetBrains Intellij ObjectHelper 插件致力于消除开发者重复性的低效工作,助力开发者将更多精力聚焦于核心业务逻辑开发,显著提升开发效率。
diff --git a/build.gradle b/build.gradle
index 731142b..44ee143 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ plugins {
}
group 'cn.bigcoder.plugin'
-version '1.4.0'
+version '1.4.1'
repositories {
mavenCentral()
@@ -28,10 +28,13 @@ intellij {
plugins = ['com.intellij.java']
}
patchPluginXml {
- sinceBuild = '211'
+ sinceBuild = '231'
untilBuild = '301.*'
changeNotes = """
- 1. new feature: Object Copy support lambda and common scene.
+ 1.Fixed the support for boolean type fields in class to json conversion.
+ 2.Added support for Map type fields in class to json conversion.
+ 3.Optimized the code experience of the Object Copy function.
+ 4.Optimized the plugin compatibility.
"""
}
test {
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
index 365eeb0..0fe3612 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/AbstractClassAnAction.java
@@ -2,6 +2,7 @@
import static cn.bigcoder.plugin.objecthelper.common.util.PsiUtils.setActionInvisible;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
@@ -25,4 +26,10 @@ public void update(@NotNull AnActionEvent anActionEvent) {
}
super.update(anActionEvent);
}
+
+ @Override
+ public @NotNull ActionUpdateThread getActionUpdateThread() {
+ return ActionUpdateThread.BGT;
+ }
+
}
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java
index 55f8358..6e8f918 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/action/ObjectCopyAction.java
@@ -9,6 +9,7 @@
import cn.bigcoder.plugin.objecthelper.generator.Generator;
import cn.bigcoder.plugin.objecthelper.generator.copy.SmartObjectCopyGenerator;
import cn.bigcoder.plugin.objecthelper.ui.ClassSearchDialog;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.CaretModel;
@@ -22,6 +23,7 @@
public class ObjectCopyAction extends AbstractClassAnAction {
+
@Override
public void actionPerformed(@NotNull AnActionEvent anAction) {
PsiClass sourcePsiClass = getOperatePsiClass(anAction);
@@ -62,6 +64,10 @@ public void actionPerformed(@NotNull AnActionEvent anAction) {
* @param copyCodeStr
*/
private void insertCode(Project project, String copyCodeStr) {
+ // 检查代码末尾是否有换行符,没有则添加
+ if (!copyCodeStr.endsWith("\n")) {
+ copyCodeStr += "\n";
+ }
Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
if (editor == null) {
return;
@@ -69,43 +75,113 @@ private void insertCode(Project project, String copyCodeStr) {
CaretModel caretModel = editor.getCaretModel();
int offset = caretModel.getOffset();
Document document = editor.getDocument();
- // 删除光标所在的变量
- int startOffset = findVariableStartOffset(document, offset);
- int endOffset = findVariableEndOffset(document, offset);
- if (startOffset >= 0 && endOffset >= 0) {
+
+ // 获取当前光标所在行号
+ int lineNumber = document.getLineNumber(offset);
+ int lineStartOffset = document.getLineStartOffset(lineNumber);
+ int lineEndOffset = document.getLineEndOffset(lineNumber);
+
+ // 检查当前行在光标之后是否有非空白字符
+ CharSequence lineText = document.getCharsSequence().subSequence(offset, lineEndOffset);
+ boolean hasNonWhitespaceAfterCursor = !lineText.toString().trim().isEmpty();
+
+ // 获取当前行的缩进
+ String indent = getLineIndent(document, lineNumber);
+ // 判断当前行是否为方法头
+ String fullLineText = document.getCharsSequence().subSequence(lineStartOffset, lineEndOffset).toString();
+ if (isMethodHeader(fullLineText)) {
+ // 若是方法头,缩进增加一格,假设一格为 4 个空格
+ indent += " ";
+ }
+
+ // 为插入的代码添加缩进
+ String indentedCopyCodeStr = addIndentToCode(copyCodeStr, indent);
+
+ if (!hasNonWhitespaceAfterCursor) {
+ // 如果光标之后没有非空白字符,删除当前行
WriteCommandAction.runWriteCommandAction(project, () -> {
- document.deleteString(startOffset, endOffset);
+ document.deleteString(lineStartOffset, lineEndOffset);
});
+ offset = lineStartOffset;
+ } else {
+ // 如果光标之后有非空白字符,将插入位置移动到下一行开头
+ int nextLineStart = document.getLineStartOffset(lineNumber + 1);
+ offset = nextLineStart;
}
+ int finalOffset = offset;
WriteCommandAction.runWriteCommandAction(project, () -> {
- document.insertString(offset, copyCodeStr);
+ document.insertString(finalOffset, indentedCopyCodeStr);
});
}
- private int findVariableStartOffset(Document document, int offset) {
- int start = offset;
- while (start > 0) {
- char c = document.getCharsSequence().charAt(start - 1);
- if (!Character.isJavaIdentifierPart(c)) {
- break;
- }
- start--;
+ /**
+ * 获取指定行的缩进
+ * @param document 文档对象
+ * @param lineNumber 行号
+ * @return 缩进字符串
+ */
+ private String getLineIndent(Document document, int lineNumber) {
+ int lineStartOffset = document.getLineStartOffset(lineNumber);
+ int lineEndOffset = document.getLineEndOffset(lineNumber);
+ CharSequence lineText = document.getCharsSequence().subSequence(lineStartOffset, lineEndOffset);
+ int indentLength = 0;
+ while (indentLength < lineText.length() && Character.isWhitespace(lineText.charAt(indentLength))) {
+ indentLength++;
+ }
+ return lineText.subSequence(0, indentLength).toString();
+ }
+
+ /**
+ * 判断当前行是否为方法头
+ * @param lineText 当前行的文本内容
+ * @return 如果是方法头返回 true,否则返回 false
+ */
+ private boolean isMethodHeader(String lineText) {
+ // 去除注释内容,避免注释中的括号影响判断
+ lineText = removeComments(lineText);
+ // 去除前后空白字符
+ lineText = lineText.trim();
+ // 简单判断,包含 ( 和 ) 且不包含 ; 认为是方法头
+ return lineText.contains("(") && lineText.contains(")") && !lineText.contains(";");
+ }
+
+
+ /**
+ * 移除字符串中的注释内容
+ * @param lineText 包含注释的字符串
+ * @return 移除注释后的字符串
+ */
+ private String removeComments(String lineText) {
+ // 移除单行注释
+ int singleCommentIndex = lineText.indexOf("//");
+ if (singleCommentIndex != -1) {
+ lineText = lineText.substring(0, singleCommentIndex);
}
- return start;
+ // 移除多行注释开始标记之后的内容(简单处理,不处理嵌套情况)
+ int multiCommentStartIndex = lineText.indexOf("/*");
+ if (multiCommentStartIndex != -1) {
+ lineText = lineText.substring(0, multiCommentStartIndex);
+ }
+ return lineText;
}
- private int findVariableEndOffset(Document document, int offset) {
- int end = offset;
- int length = document.getTextLength();
- while (end < length) {
- char c = document.getCharsSequence().charAt(end);
- if (!Character.isJavaIdentifierPart(c)) {
- break;
+ /**
+ * 为代码的每一行添加缩进
+ * @param code 原始代码
+ * @param indent 缩进字符串
+ * @return 添加缩进后的代码
+ */
+ private String addIndentToCode(String code, String indent) {
+ StringBuilder indentedCode = new StringBuilder();
+ String[] lines = code.split("\\r?\\n");
+ for (int i = 0; i < lines.length; i++) {
+ indentedCode.append(indent).append(lines[i]);
+ if (i < lines.length - 1) {
+ indentedCode.append("\n");
}
- end++;
}
- return end;
+ return indentedCode.toString();
}
@Override
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
index 297cf03..a1d4c22 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/constant/JavaClassName.java
@@ -10,6 +10,7 @@ public class JavaClassName {
public static final String LONG_TYPE = "java.lang.Long";
public static final String SHORT_TYPE = "java.lang.Short";
public static final String BYTE_TYPE = "java.lang.Byte";
+ public static final String BOOLEAN_TYPE = "java.lang.Boolean";
public static final String DOUBLE_TYPE = "java.lang.Double";
public static final String FLOAT_TYPE = "java.lang.Float";
public static final String DATE_TYPE = "java.util.Date";
@@ -22,6 +23,7 @@ public class JavaClassName {
public static final String BASE_BYTE_TYPE = "byte";
public static final String BASE_DOUBLE_TYPE = "double";
public static final String BASE_FLOAT_TYPE = "float";
+ public static final String BASE_BOOL_TYPE = "boolean";
public static final String COLLECTION_TYPE = "java.util.Collection";
public static final String MAP_TYPE = "java.util.Map";
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
index 9dccef7..ea71389 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/common/util/PsiTypeUtils.java
@@ -43,6 +43,8 @@ public class PsiTypeUtils {
DATA_TYPES.add(LOCAL_DATE_TYPE);
DATA_TYPES.add(LOCAL_DATE_TIME_TYPE);
DATA_TYPES.add(BIG_DECIMAL);
+ DATA_TYPES.add(BOOLEAN_TYPE);
+ DATA_TYPES.add(BASE_BOOL_TYPE);
}
/**
@@ -76,6 +78,9 @@ public static Object getDataTypeDefaultValue(String canonicalText) {
case FLOAT_TYPE:
case BASE_FLOAT_TYPE:
return 1.1f;
+ case BOOLEAN_TYPE:
+ case BASE_BOOL_TYPE:
+ return true;
case DATE_TYPE:
return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
case LOCAL_DATE_TYPE:
diff --git a/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java b/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
index d490bfe..4d88424 100644
--- a/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
+++ b/src/main/java/cn/bigcoder/plugin/objecthelper/generator/AbstractDataObjectGenerator.java
@@ -1,5 +1,6 @@
package cn.bigcoder.plugin.objecthelper.generator;
+import cn.bigcoder.plugin.objecthelper.common.constant.JavaClassName;
import cn.bigcoder.plugin.objecthelper.common.util.PsiTypeUtils;
import cn.bigcoder.plugin.objecthelper.common.util.PsiUtils;
import com.google.common.collect.Maps;
@@ -23,66 +24,91 @@
**/
public abstract class AbstractDataObjectGenerator implements Generator {
- private PsiClass psiClass;
+ private PsiClass psiClass;
- public AbstractDataObjectGenerator(PsiClass psiClass) {
- this.psiClass = psiClass;
- }
-
- /**
- * 保存已经解析过的自定义类型名称,防止出现递归嵌套的情况
- */
- private Set recursiveCache = Sets.newHashSet();
+ public AbstractDataObjectGenerator(PsiClass psiClass) {
+ this.psiClass = psiClass;
+ }
- protected Map processFields() {
- return processFields(psiClass);
- }
+ /**
+ * 保存已经解析过的自定义类型名称,防止出现递归嵌套的情况
+ */
+ private Set recursiveCache = Sets.newHashSet();
- protected Map processFields(PsiClass psiClass) {
- Map result = Maps.newLinkedHashMap();
- // 当前类所有字段
- List allPsiFields = PsiUtils.getAllPsiFields(psiClass);
- if (CollectionUtils.isEmpty(allPsiFields)) {
- return result;
+ protected Map processFields() {
+ return processFields(psiClass);
}
- for (PsiField psiField : allPsiFields) {
- result.put(psiField.getName(), processField(psiField.getType()));
+
+ protected Map processFields(PsiClass psiClass) {
+ Map result = Maps.newLinkedHashMap();
+ // 当前类所有字段
+ List allPsiFields = PsiUtils.getAllPsiFields(psiClass);
+ if (CollectionUtils.isEmpty(allPsiFields)) {
+ return result;
+ }
+ for (PsiField psiField : allPsiFields) {
+ // 过滤掉静态字段
+ if (!psiField.hasModifierProperty(com.intellij.psi.PsiModifier.STATIC)) {
+ result.put(psiField.getName(), processField(psiField.getType()));
+ }
+ }
+ return result;
}
- return result;
- }
- private Object processField(PsiType psiType) {
- Object defaultValue = null;
- if (PsiTypeUtils.isDataType(psiType)) {
- //如果是数据类型
- defaultValue = PsiTypeUtils.getDataTypeDefaultValue(psiType.getCanonicalText());
- } else if (PsiTypeUtils.isArrayType(psiType)) {
- //如果是数组类型
- List