From 84f8c77f34b3084706fe6491e288a5d3cb77a393 Mon Sep 17 00:00:00 2001 From: mjj Date: Wed, 8 Aug 2018 13:55:45 +0800 Subject: [PATCH] release 1.1 --- .gitignore | 4 +- build.gradle | 2 +- src/main/java/asd.java | 6 -- .../kotlin/action/GenerateFindViewAction.kt | 44 +++++----- src/main/kotlin/extensions/DataExtensions.kt | 14 +--- src/main/kotlin/extensions/PsiExtensions.kt | 4 - src/main/kotlin/helper/JavaFileWriteHelper.kt | 83 +++++++++++++++++++ src/main/kotlin/helper/KtFileWriteHelper.kt | 81 ++++++++++++++++++ src/main/kotlin/ui/JavaDialog.form | 25 ++++-- src/main/kotlin/ui/JavaDialog.kt | 39 +++++++-- src/main/kotlin/ui/KotlinDialog.form | 21 +++-- src/main/kotlin/ui/KotlinDialog.kt | 36 ++++---- src/main/kotlin/ui/ViewTableModel.kt | 12 +-- src/main/kotlin/ui/XMLDialog.form | 10 ++- src/main/kotlin/ui/XMLDialog.kt | 4 +- src/main/kotlin/utils/JavaFileWriteUtils.java | 39 --------- src/main/kotlin/utils/KtFileWriteUtils.kt | 31 ------- src/main/resources/META-INF/plugin.xml | 3 +- 18 files changed, 297 insertions(+), 161 deletions(-) delete mode 100644 src/main/java/asd.java create mode 100644 src/main/kotlin/helper/JavaFileWriteHelper.kt create mode 100644 src/main/kotlin/helper/KtFileWriteHelper.kt delete mode 100644 src/main/kotlin/utils/JavaFileWriteUtils.java delete mode 100644 src/main/kotlin/utils/KtFileWriteUtils.kt diff --git a/.gitignore b/.gitignore index a9a796a..15fec7e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ /build /captures .externalNativeBuild - -*.apk +/src/test +/out diff --git a/build.gradle b/build.gradle index 888771d..f8b214c 100644 --- a/build.gradle +++ b/build.gradle @@ -24,4 +24,4 @@ dependencies { } group 'me.majiajie' -version '1.0' \ No newline at end of file +version '1.1' \ No newline at end of file diff --git a/src/main/java/asd.java b/src/main/java/asd.java deleted file mode 100644 index 6c9d2b6..0000000 --- a/src/main/java/asd.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Created by mjj on 2018/7/24 - */ -public class asd { - -} diff --git a/src/main/kotlin/action/GenerateFindViewAction.kt b/src/main/kotlin/action/GenerateFindViewAction.kt index 1c9b211..31c691d 100644 --- a/src/main/kotlin/action/GenerateFindViewAction.kt +++ b/src/main/kotlin/action/GenerateFindViewAction.kt @@ -35,44 +35,43 @@ class GenerateFindViewAction : AnAction() { // 获取焦点文件 val psiFile = e.getData(LangDataKeys.PSI_FILE) if (psiFile == null) { - Messages.showWarningDialog(project, "文件无法识别", "异常") + Messages.showWarningDialog(project, "No focus file", "ERROE") return } when (psiFile.fileType.name.toUpperCase()) { "KOTLIN" -> { - if (checkSelectedText(e, project)) { - showGenerateKotlinCodeDialog(project,psiFile,searchFileAndGetElementList(project, psiFile)) + if (checkSelectedText(e)) { + showGenerateKotlinCodeDialog(project, psiFile, searchFileAndGetElementList(project, psiFile)) + } else { + Messages.showErrorDialog("Layout file name is not selected", "ERROE") } } "JAVA" -> { - if (checkSelectedText(e, project)) { - showGenerateJavaCodeDialog(project,psiFile,searchFileAndGetElementList(project, psiFile)) + if (checkSelectedText(e)) { + showGenerateJavaCodeDialog(project, psiFile, searchFileAndGetElementList(project, psiFile)) + } else { + Messages.showErrorDialog("Layout file name is not selected", "ERROE") } } "XML" -> { showGenerateXMLDialog(psiFile, psiFile.getAndroidViewIds()) } - else -> Messages.showWarningDialog(project, "不支持的文件类型: " + psiFile.fileType.name, "警告") + else -> Messages.showWarningDialog(project, "This file type (${psiFile.fileType.name}) is not supported", "Warning") } } /** * 检查是否选中字符串 */ - private fun checkSelectedText(e: AnActionEvent, project: Project): Boolean { + private fun checkSelectedText(e: AnActionEvent): Boolean { // 获取选中内容 val editor = e.getData(PlatformDataKeys.EDITOR) ?: return false val model = editor.selectionModel mSelectedText = model.selectedText - if (TextUtils.isEmpty(mSelectedText)) { - Messages.showErrorDialog(project, "未选择layout文件名", "错误") - return false - } - - return true + return !TextUtils.isEmpty(mSelectedText) } /** @@ -82,20 +81,19 @@ class GenerateFindViewAction : AnAction() { val file = AndroidLayoutUtils.findLayoutResourceFile(psiFile, project, "$mSelectedText.xml") - if (file == null) { - Messages.showErrorDialog(project, "未找到选中的布局文件", "错误") - return ArrayList() + return if (file == null) { + ArrayList() + } else { + // 解析布局文件中所有View的ID + file.getAndroidViewIds() } - - // 解析布局文件中所有View的ID - return file.getAndroidViewIds() } /** * 显示生成代码的Dialog(Kotlin) */ - private fun showGenerateKotlinCodeDialog(project: Project,psiFile: PsiFile,elements: ArrayList) { - val dialog = KotlinDialog(project,psiFile,elements) + private fun showGenerateKotlinCodeDialog(project: Project, psiFile: PsiFile, elements: ArrayList) { + val dialog = KotlinDialog(project, psiFile, elements) dialog.pack() dialog.isVisible = true } @@ -112,8 +110,8 @@ class GenerateFindViewAction : AnAction() { /** * 显示生成代码的Dialog(JAVA) */ - private fun showGenerateJavaCodeDialog(project: Project,psiFile: PsiFile,elements: ArrayList) { - val dialog = JavaDialog(elements) + private fun showGenerateJavaCodeDialog(project: Project, psiFile: PsiFile, elements: ArrayList) { + val dialog = JavaDialog(project, psiFile, elements) dialog.pack() dialog.isVisible = true } diff --git a/src/main/kotlin/extensions/DataExtensions.kt b/src/main/kotlin/extensions/DataExtensions.kt index 2f6b0dd..d92a8ae 100644 --- a/src/main/kotlin/extensions/DataExtensions.kt +++ b/src/main/kotlin/extensions/DataExtensions.kt @@ -3,6 +3,9 @@ package extensions import bean.Element import bean.ViewInfo import com.intellij.openapi.project.Project +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiField +import com.intellij.psi.PsiFile import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPsiFactory import java.awt.Toolkit @@ -30,16 +33,6 @@ fun String.firstToUpperCase(): String { */ fun List.toViewInfoList() = this.map { ViewInfo(true, it) } -/** - * 转换成KtProperty - */ -fun List.toKtProperty(project: Project, addM: Boolean, isPrivate: Boolean, rootView: String): List { - val ktPsiFactory = KtPsiFactory(project) - return this.filter { it.isChecked }.map { - ktPsiFactory.createProperty(it.getKTString(addM, isPrivate, rootView)) - } -} - /** * 生成Kotlin代码 */ @@ -82,7 +75,6 @@ fun List.gengrateJavaCode(addM: Boolean, rootView: String, isPrivate: val findViewStr = infos.joinToString("\n") { it.getJavaFindViewString(addM, isTarget26, rootView) } return "$fieldStr\n\n$findViewStr" - } /** diff --git a/src/main/kotlin/extensions/PsiExtensions.kt b/src/main/kotlin/extensions/PsiExtensions.kt index f2303be..b2e6c8c 100644 --- a/src/main/kotlin/extensions/PsiExtensions.kt +++ b/src/main/kotlin/extensions/PsiExtensions.kt @@ -11,10 +11,6 @@ import com.intellij.psi.xml.XmlTag import utils.AndroidLayoutUtils import java.util.ArrayList -/** - * Psi文件处理扩展 - */ - /** * 在指定范围内寻找文件 diff --git a/src/main/kotlin/helper/JavaFileWriteHelper.kt b/src/main/kotlin/helper/JavaFileWriteHelper.kt new file mode 100644 index 0000000..70a9065 --- /dev/null +++ b/src/main/kotlin/helper/JavaFileWriteHelper.kt @@ -0,0 +1,83 @@ +package helper + +import bean.ViewInfo +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.project.Project +import com.intellij.psi.* +import com.intellij.psi.util.PsiTreeUtil + +/** + * Java文件写入帮助类 + */ +class JavaFileWriteHelper(project: Project, + private val psiFile: PsiFile, + private val viewInfos: List, + private val addM: Boolean, + private val isPrivate: Boolean, + private val rootView: String, + private val isTarget26: Boolean +) : WriteCommandAction.Simple(project, psiFile) { + + override fun run() { + val psiClass = PsiTreeUtil.findChildOfAnyType(psiFile, PsiClass::class.java) + if (psiClass == null) { + throw RuntimeException("Java class not found") + } else { + val psiElementFactory = JavaPsiFacade.getElementFactory(project) + // 已经存在的变量 + val oldFieldNameList = psiClass.allFields.map { it.name } + // 生成变量 + val fieldList = getJavaField(psiElementFactory) + // 添加变量 + fieldList.forEach { + // 已经存在同名变量就不添加 + if (!oldFieldNameList.contains(it.name)) { + psiClass.add(it) + } + } + + // 检查是否存在'initView()'方法 + val initMethod = psiClass.findMethodsByName("initView", true).firstOrNull { it.parameters.isEmpty() } + if (initMethod != null) { + getJavaStatement(psiElementFactory).forEach { + initMethod.body?.add(it) + } + } else {// 不存在就创建initView方法 + val method = createInitViewMethod(psiElementFactory) + psiClass.add(method) + } + } + } + + /** + * 获取成Java代码变量 + */ + private fun getJavaField(psiElementFactory: PsiElementFactory) + : List { + return viewInfos.filter { it.isChecked } + .map { it.getJavaFieldString(addM, isPrivate) } + .map { psiElementFactory.createFieldFromText(it, psiFile) } + } + + /** + * 获取Java参数变量 + */ + private fun getJavaStatement(psiElementFactory: PsiElementFactory) + : List { + return viewInfos.filter { it.isChecked } + .map { it.getJavaFindViewString(addM, isTarget26, rootView) } + .map { psiElementFactory.createStatementFromText(it, psiFile) } + } + + /** + * 创建initView方法 + */ + private fun createInitViewMethod(psiElementFactory: PsiElementFactory): PsiMethod { + return psiElementFactory.createMethodFromText( + """public void initView(){ + ${viewInfos.filter { it.isChecked }.map { it.getJavaFindViewString(addM, isTarget26, rootView) }.joinToString("\n") { it }} + } + """.trimIndent(), psiFile) + } + +} diff --git a/src/main/kotlin/helper/KtFileWriteHelper.kt b/src/main/kotlin/helper/KtFileWriteHelper.kt new file mode 100644 index 0000000..dc99b0d --- /dev/null +++ b/src/main/kotlin/helper/KtFileWriteHelper.kt @@ -0,0 +1,81 @@ +package helper + +import bean.ViewInfo +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.psi.* + +/** + * Kt类文件写入帮助 + */ +class KtFileWriteHelper(project: Project, + private val psiFile: PsiFile, + private val viewInfos: List, + private val addM: Boolean, + private val isPrivate: Boolean, + private val rootView: String) + : WriteCommandAction.Simple(project, psiFile) { + + override fun run() { + val ktClass: KtClass? = PsiTreeUtil.findChildOfAnyType(psiFile, KtClass::class.java) + + val ktBoday = ktClass?.getBody() + if (ktBoday == null) { + throw RuntimeException("kotlin class body not found") + } else { + val propertyList = getKtPropertyList() + + val firstProperty: PsiElement? = ktBoday.declarations.firstOrNull { it is KtProperty } + writeFile(KtPsiFactory(project), ktBoday, propertyList, firstProperty + ?: ktBoday.lBrace!!, firstProperty == null) + } + } + + /** + * 写入 + */ + private fun writeFile(ktPsiFactory: KtPsiFactory, ktBoday: KtClassBody, list: List, psiElement: PsiElement, toAfter: Boolean) { + + var index = 0 + val last = list.size - 1 + + // 已经存在的变量 + val oldPropertyNames = ktBoday.declarations.filter { it is KtProperty }.map { it.name } + + var e = psiElement + for (i in 0..last) { + val p = list[i] + if (!oldPropertyNames.contains(p.name)) { + if (toAfter) {// 往后添加变量,就添加一个空行 + e = ktBoday.addAfter(p, e) + ktBoday.addBefore(ktPsiFactory.createNewLine(2), e) + } else { + e = ktBoday.addBefore(p, e) + } + index = i + 1 + break + } + } + + for (i in index..last) { + val p = list[i] + if (!oldPropertyNames.contains(p.name)) { + e = ktBoday.addAfter(p, e) + } + } + } + + /** + * 获取KtProperty + */ + private fun getKtPropertyList(): List { + val ktPsiFactory = KtPsiFactory(project) + return viewInfos.filter { it.isChecked }.map { + ktPsiFactory.createProperty(it.getKTString(addM, isPrivate, rootView)) + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/ui/JavaDialog.form b/src/main/kotlin/ui/JavaDialog.form index f56e337..7666c75 100644 --- a/src/main/kotlin/ui/JavaDialog.form +++ b/src/main/kotlin/ui/JavaDialog.form @@ -3,7 +3,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -34,24 +34,34 @@ - + - + + + + + + + + + - + + + @@ -66,7 +76,9 @@ - + + + @@ -75,6 +87,7 @@ + diff --git a/src/main/kotlin/ui/JavaDialog.kt b/src/main/kotlin/ui/JavaDialog.kt index 88c9a2f..e2a681f 100644 --- a/src/main/kotlin/ui/JavaDialog.kt +++ b/src/main/kotlin/ui/JavaDialog.kt @@ -1,18 +1,23 @@ package ui import bean.* +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.psi.PsiFile import extensions.gengrateJavaCode import extensions.toClipboard import extensions.toViewInfoList +import helper.JavaFileWriteHelper import javax.swing.* import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener -class JavaDialog(list: List) : BaseJDialog() { +class JavaDialog(private val project: Project, private val psiFile: PsiFile, list: List) : BaseJDialog() { override var contentPane: JPanel? = null override var buttonOK: JButton? = null override var buttonCancel: JButton? = null + private var buttonCopyCode: JButton? = null private var tvCode: JTextArea? = null private var viewTable: JTable? = null private var selectAllButton: JButton? = null @@ -40,7 +45,7 @@ class JavaDialog(list: List) : BaseJDialog() { title = "Generate findViewById code (JAVA)" // 设置大小和位置 - layoutSize(700, 400) + layoutSize(700, 520) init() @@ -121,6 +126,12 @@ class JavaDialog(list: List) : BaseJDialog() { } }) + // 复制代码 + buttonCopyCode!!.addActionListener { + tvCode!!.text.toClipboard() + dispose() + } + } /** @@ -136,8 +147,17 @@ class JavaDialog(list: List) : BaseJDialog() { * 确认 */ override fun onOK() { - tvCode!!.text.toClipboard() - dispose() + try { + val addM = addMCheckBox!!.isSelected + val isPrivate = isPrivateCheckBox!!.isSelected + val rootView = if (addRootViewCheckBox!!.isSelected) edtRootView!!.text else "" + val isTarget26 = isTarget26CheckBox!!.isSelected + JavaFileWriteHelper(project, psiFile, mViewInfoList, addM, isPrivate, rootView,isTarget26) + .execute() + dispose() + } catch (e: Exception) { + Messages.showErrorDialog(e.message, "Generate code error") + } } /** @@ -151,8 +171,15 @@ class JavaDialog(list: List) : BaseJDialog() { * 生成代码 */ private fun generateCode() { - tvCode!!.text = mViewInfoList.gengrateJavaCode(addMCheckBox!!.isSelected, if (addRootViewCheckBox!!.isSelected) edtRootView!!.text else "", - isPrivateCheckBox!!.isSelected, isTarget26CheckBox!!.isSelected) + val addM = addMCheckBox!!.isSelected + val isPrivate = isPrivateCheckBox!!.isSelected + val rootView = if (addRootViewCheckBox!!.isSelected) edtRootView!!.text else "" + val isTarget26 = isTarget26CheckBox!!.isSelected + + tvCode!!.text = mViewInfoList.gengrateJavaCode(addM, rootView, isPrivate, isTarget26) + + // 将光标移动到开始位置(用于控制垂直滚动在代码生成后一直在顶部) + tvCode!!.caretPosition = 0 } } diff --git a/src/main/kotlin/ui/KotlinDialog.form b/src/main/kotlin/ui/KotlinDialog.form index 1e71d1e..b946d82 100644 --- a/src/main/kotlin/ui/KotlinDialog.form +++ b/src/main/kotlin/ui/KotlinDialog.form @@ -3,9 +3,12 @@ - + - + + + + @@ -59,7 +62,9 @@ - + + + @@ -67,14 +72,17 @@ - + + - + + + @@ -83,7 +91,8 @@ - + + diff --git a/src/main/kotlin/ui/KotlinDialog.kt b/src/main/kotlin/ui/KotlinDialog.kt index 1898633..7247c07 100644 --- a/src/main/kotlin/ui/KotlinDialog.kt +++ b/src/main/kotlin/ui/KotlinDialog.kt @@ -3,22 +3,19 @@ package ui import bean.* import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages -import com.intellij.psi.PsiClass import com.intellij.psi.PsiFile -import com.intellij.psi.util.PsiTreeUtil import extensions.gengrateKTCode import extensions.toClipboard -import extensions.toKtProperty import extensions.toViewInfoList -import org.jetbrains.kotlin.psi.KtClass -import utils.KtFileWriteUtils +import helper.KtFileWriteHelper import javax.swing.* /** * Kotlin文件中生成时使用 */ -class KotlinDialog(val project: Project,val psiFile: PsiFile, list: List) : BaseJDialog() { +class KotlinDialog(private val project: Project, private val psiFile: PsiFile, list: List) + : BaseJDialog() { override var contentPane: JPanel? = null override var buttonOK: JButton? = null @@ -37,7 +34,7 @@ class KotlinDialog(val project: Project,val psiFile: PsiFile, list: List(project, psiFile, mViewInfoList, addM, isPrivate, rootView) + .execute() dispose() + } catch (e: Exception) { + Messages.showErrorDialog(e.message, "Generate code error") } - } /** @@ -151,7 +150,14 @@ class KotlinDialog(val project: Project,val psiFile: PsiFile, list: List return "select" - 1 -> return "type" - 2 -> return "id" - 3 -> return "name" - else -> return "unknow" + return when (column) { + 0 -> "select" + 1 -> "type" + 2 -> "id" + 3 -> "name" + else -> "unknow" } } diff --git a/src/main/kotlin/ui/XMLDialog.form b/src/main/kotlin/ui/XMLDialog.form index 1bd18e8..ef8d6c6 100644 --- a/src/main/kotlin/ui/XMLDialog.form +++ b/src/main/kotlin/ui/XMLDialog.form @@ -3,7 +3,7 @@ - + @@ -51,7 +51,9 @@ - + + + @@ -66,7 +68,9 @@ - + + + diff --git a/src/main/kotlin/ui/XMLDialog.kt b/src/main/kotlin/ui/XMLDialog.kt index daeed51..03380b3 100644 --- a/src/main/kotlin/ui/XMLDialog.kt +++ b/src/main/kotlin/ui/XMLDialog.kt @@ -49,7 +49,7 @@ class XMLDialog(private val file: PsiFile, list: List) : BaseJDialog() title = "Generate findViewById code (XML)" // 设置大小和位置 - layoutSize(800, 400) + layoutSize(800, 550) init() @@ -279,5 +279,7 @@ class XMLDialog(private val file: PsiFile, list: List) : BaseJDialog() } } + // 将光标移动到开始位置(用于控制垂直滚动在代码生成后一直在顶部) + tvCode!!.caretPosition = 0 } } diff --git a/src/main/kotlin/utils/JavaFileWriteUtils.java b/src/main/kotlin/utils/JavaFileWriteUtils.java deleted file mode 100644 index 2b67b4f..0000000 --- a/src/main/kotlin/utils/JavaFileWriteUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package utils; - -import com.intellij.lang.Language; -import com.intellij.lang.LanguageParserDefinitions; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.project.Project; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.PsiClassImplUtil; -import com.intellij.psi.util.PsiClassUtil; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; - -/** - * Created by mjj on 2018/7/28 - */ -public class JavaFileWriteUtils { - - public JavaFileWriteUtils(Project project, PsiFile psiFile) { - PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project); - - KtPsiFactory ktPsiFactory = KtPsiFactoryKt.KtPsiFactory(project); - // 创建变量 - KtProperty ktProperty = ktPsiFactory.createProperty("private","test","View",false,"lazy {}"); - - final PsiClass psiClass = PsiTreeUtil.findChildOfAnyType(psiFile.getOriginalElement(), PsiClass.class); - psiClass.add(ktProperty); - - WriteCommandAction.runWriteCommandAction(project, new Runnable() { - @Override - public void run() { - - } - }); - } -} diff --git a/src/main/kotlin/utils/KtFileWriteUtils.kt b/src/main/kotlin/utils/KtFileWriteUtils.kt deleted file mode 100644 index d293194..0000000 --- a/src/main/kotlin/utils/KtFileWriteUtils.kt +++ /dev/null @@ -1,31 +0,0 @@ -package utils - -import bean.ViewInfo -import com.intellij.openapi.command.WriteCommandAction -import com.intellij.openapi.project.Project -import com.intellij.psi.JavaPsiFacade -import com.intellij.psi.PsiClass -import com.intellij.psi.util.PsiClassUtil -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtProperty -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.uast.getContainingClass - -/** - * kotlin 文件写入工具 - */ -object KtFileWriteUtils{ - - fun addPropertyToKtClass(project:Project,ktClass:KtClass,list:List){ - - WriteCommandAction.runWriteCommandAction(project) { -// val ktPsiFactory = KtPsiFactory(project) -// // 创建变量 -// val ktProperty = ktPsiFactory.createProperty("private", "test", "View", false, "lazy {}") - list.forEach { - ktClass.getContainingClass()!!.add(it) -// ktClass.addAfter(it,ktClass.getClassOrInterfaceKeyword()) - } - } - } -} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 6d3131e..8253c58 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -7,7 +7,8 @@ Generate Android 'findViewById' code.Support for Java and Kotlin. - 1.0 ... + - V1.1 + add the function of automatically generating code in the Java or Kotlin class