From ed7cc145ed0aa10f08cd5bce4af67d6230448c79 Mon Sep 17 00:00:00 2001 From: tangcent Date: Sun, 24 Mar 2024 18:09:25 +0800 Subject: [PATCH] fix: resolve comment for custom enum field --- .../com/itangcent/common/kit/KVUtils.kt | 2 +- .../main/kotlin/com/itangcent/utils/AnyKit.kt | 8 ++ gradle.properties | 2 +- .../plugin/api/export/core/CommentResolver.kt | 12 +-- .../api/export/core/RequestClassExporter.kt | 17 +++- .../helper/RemoteConfigSettingsHelper.kt | 2 +- .../api/export/core/CommentResolverTest.kt | 86 +++++++++++-------- .../spring/SpringRequestClassExporterTest.kt | 4 +- ...est.testExportFromTestCtrlWithExpanded.txt | 5 +- ....testExportFromTestCtrlWithOutExpanded.txt | 5 +- 10 files changed, 88 insertions(+), 55 deletions(-) diff --git a/common-api/src/main/kotlin/com/itangcent/common/kit/KVUtils.kt b/common-api/src/main/kotlin/com/itangcent/common/kit/KVUtils.kt index 8aa551c3a..7867c46f2 100644 --- a/common-api/src/main/kotlin/com/itangcent/common/kit/KVUtils.kt +++ b/common-api/src/main/kotlin/com/itangcent/common/kit/KVUtils.kt @@ -48,7 +48,7 @@ object KVUtils { */ fun getConstantDesc(constants: List>): String? { return constants.asSequence() - .mapNotNull { concat(it["name"]?.toString(), it["desc"]?.toString()) } + .mapNotNull { concat((it["name"] ?: it["value"])?.toString(), it["desc"]?.toString()) } .joinToString("\n") } diff --git a/common-api/src/main/kotlin/com/itangcent/utils/AnyKit.kt b/common-api/src/main/kotlin/com/itangcent/utils/AnyKit.kt index 371eef5ce..67c67bbba 100644 --- a/common-api/src/main/kotlin/com/itangcent/utils/AnyKit.kt +++ b/common-api/src/main/kotlin/com/itangcent/utils/AnyKit.kt @@ -54,4 +54,12 @@ fun Map<*, *>.subMutable(key: String): MutableMap? { } } return null +} + +fun > T?.emptyIf(another: () -> T): T { + return if (this.isNullOrEmpty()) { + another() + } else { + this + } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 95a803662..b8157bb10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ plugin_version=2.6.8.212.0 kotlin.code.style=official kotlin_version=1.8.0 junit_version=5.9.2 -itangcent_intellij_version=1.6.3 \ No newline at end of file +itangcent_intellij_version=1.6.4 \ No newline at end of file diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolver.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolver.kt index e7978d472..79916f73b 100644 --- a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolver.kt +++ b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolver.kt @@ -16,6 +16,7 @@ import com.itangcent.intellij.jvm.duck.SingleDuckType import com.itangcent.intellij.jvm.duck.SingleUnresolvedDuckType import com.itangcent.intellij.logger.Logger import com.itangcent.intellij.psi.ClassRuleKeys +import com.itangcent.utils.emptyIf @Singleton class CommentResolver { @@ -74,9 +75,10 @@ class CommentResolver { if (duckType is SingleDuckType) { val enumClass = duckType.psiClass() - val constants = psiClassHelper!!.parseEnumConstant(enumClass) + val constants = psiClassHelper!!.resolveEnumOrStatic(context, enumClass, null, "") {} + .emptyIf { psiClassHelper.parseEnumConstant(enumClass) } if (constants.isEmpty()) { - logger!!.error("nothing be found at:$convertTo") + logger!!.error("nothing be found for:${duckType.canonicalText()}") return null } @@ -116,9 +118,9 @@ class CommentResolver { } val enumClass = jvmClassHelper.resolveClassInType(psiType)!! - val constants = psiClassHelper!!.parseEnumConstant(enumClass) - if (constants.isEmpty()) { - logger!!.error("nothing be found at:$convertTo") + val constants = psiClassHelper!!.resolveEnumOrStatic(context, enumClass, null, "") {} + if (constants.isNullOrEmpty()) { + logger!!.error("nothing be found for:${psiType.canonicalText}") return null } diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/RequestClassExporter.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/RequestClassExporter.kt index 336bf086d..e4aafcf44 100644 --- a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/RequestClassExporter.kt +++ b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/api/export/core/RequestClassExporter.kt @@ -123,6 +123,7 @@ abstract class RequestClassExporter : ClassExporter { !hasApi(cls) -> { return false } + shouldIgnore(cls) -> { logger.info("ignore class:$clsQualifiedName") return true @@ -246,10 +247,12 @@ abstract class RequestClassExporter : ClassExporter { logger.error("error to parse additional header: $headerStr") return@cache null } + header.name.isNullOrBlank() -> { logger.error("no name had be found in: $headerStr") return@cache null } + else -> return@cache header } }?.let { @@ -271,10 +274,12 @@ abstract class RequestClassExporter : ClassExporter { logger.error("error to parse additional param: $paramStr") return@cache null } + param.name.isNullOrBlank() -> { logger.error("no name had be found in: $paramStr") return@cache null } + else -> return@cache param } }?.let { @@ -300,10 +305,12 @@ abstract class RequestClassExporter : ClassExporter { logger.error("error to parse additional response header: $headerStr") return@cache null } + header.name.isNullOrBlank() -> { logger.error("no name had be found in: $headerStr") return@cache null } + else -> return@cache header } }?.let { @@ -422,7 +429,7 @@ abstract class RequestClassExporter : ClassExporter { } } - if (methodReturnMainType != null) { + if (methodReturnMain == null && methodReturnMainType != null) { commentResolver.resolveCommentForType(methodReturnMainType, methodExportContext.psi())?.let { ultimateComment.appendLine(it) } @@ -437,9 +444,11 @@ abstract class RequestClassExporter : ClassExporter { ) } else { if (!KVUtils.addKeyComment(typedResponse, methodReturnMain, ultimateCommentStr)) { - requestBuilderListener.appendResponseBodyDesc(methodExportContext, + requestBuilderListener.appendResponseBodyDesc( + methodExportContext, response, - ultimateCommentStr) + ultimateCommentStr + ) } } } @@ -787,12 +796,14 @@ abstract class RequestClassExporter : ClassExporter { duckType, method.psi(), this.intelligentSettingsHelper.jsonOptionForOutput(JsonOption.READ_COMMENT) ) + this.intelligentSettingsHelper.inferEnable() && !duckTypeHelper.isQualified(duckType) -> { logger.info("try infer return type of method[" + PsiClassUtils.fullNameOfMethod(method.psi()) + "]") methodReturnInferHelper!!.inferReturn(method.psi()) // actionContext!!.callWithTimeout(20000) { methodReturnInferHelper.inferReturn(method) } } + else -> psiClassHelper!!.getTypeObject( duckType, method.psi(), this.intelligentSettingsHelper.jsonOptionForOutput(JsonOption.READ_COMMENT) diff --git a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/settings/helper/RemoteConfigSettingsHelper.kt b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/settings/helper/RemoteConfigSettingsHelper.kt index 5c6b93fa3..18db20ccf 100644 --- a/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/settings/helper/RemoteConfigSettingsHelper.kt +++ b/idea-plugin/src/main/kotlin/com/itangcent/idea/plugin/settings/helper/RemoteConfigSettingsHelper.kt @@ -52,7 +52,7 @@ class RemoteConfigSettingsHelper { } private fun getContentTypeFromUrl(url: String): String { - return url.substringAfterLast('.').ifBlank { "properties" } + return url.substringBefore('?').substringAfterLast('.').ifBlank { "properties" } } fun refreshConfig(url: String): String? { diff --git a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolverTest.kt b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolverTest.kt index 9ce536cae..49cecc61a 100644 --- a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolverTest.kt +++ b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/CommentResolverTest.kt @@ -2,7 +2,6 @@ package com.itangcent.idea.plugin.api.export.core import com.google.inject.Inject import com.intellij.psi.PsiClass -import com.itangcent.idea.plugin.api.export.core.CommentResolver import com.itangcent.intellij.jvm.JvmClassHelper import com.itangcent.intellij.jvm.duck.SingleDuckType import com.itangcent.testFramework.PluginContextLightCodeInsightFixtureTestCase @@ -34,7 +33,8 @@ internal class CommentResolverTest : PluginContextLightCodeInsightFixtureTestCas override fun customConfig(): String { //language=Properties - return "json.rule.enum.convert[com.itangcent.constant.JavaVersion]=~#name" + return "json.rule.enum.convert[com.itangcent.constant.JavaVersion]=~#name\n" + + "json.rule.enum.convert[com.itangcent.constant.UserType]=~#type" } fun testResolveCommentForType() { @@ -42,51 +42,61 @@ internal class CommentResolverTest : PluginContextLightCodeInsightFixtureTestCas val userInfoDuckType = SingleDuckType(userInfoPsiClass) val userCtrlDuckType = SingleDuckType(userCtrlPsiClass) val javaVersionDuckType = SingleDuckType(javaVersionPsiClass) - assertEquals("ADMIN :administration\n" + - "MEM :a person, an animal or a plant\n" + - "GUEST :Anonymous visitor", commentResolver.resolveCommentForType(userTypeDuckType, userTypePsiClass)) + assertEquals( + "1 :administration\n" + + "2 :a person, an animal or a plant\n" + + "3 :Anonymous visitor", + commentResolver.resolveCommentForType(userTypeDuckType, userTypePsiClass) + ) assertEquals(null, commentResolver.resolveCommentForType(userInfoDuckType, userInfoPsiClass)) assertEquals(null, commentResolver.resolveCommentForType(userCtrlDuckType, userCtrlPsiClass)) - assertEquals("0.9 :The Java version reported by Android. This is not an official Java version number.\n" + - "1.1 :Java 1.1.\n" + - "1.2 :Java 1.2.\n" + - "1.3 :Java 1.3.\n" + - "1.4 :Java 1.4.\n" + - "1.5 :Java 1.5.\n" + - "1.6 :Java 1.6.\n" + - "1.7 :Java 1.7.\n" + - "1.8 :Java 1.8.\n" + - "9 :Java 1.9.\n" + - "9 :Java 9\n" + - "10 :Java 10\n" + - "11 :Java 11\n" + - "12 :Java 12\n" + - "13 :Java 13", commentResolver.resolveCommentForType(javaVersionDuckType, javaVersionPsiClass)) + assertEquals( + "0.9 :The Java version reported by Android. This is not an official Java version number.\n" + + "1.1 :Java 1.1.\n" + + "1.2 :Java 1.2.\n" + + "1.3 :Java 1.3.\n" + + "1.4 :Java 1.4.\n" + + "1.5 :Java 1.5.\n" + + "1.6 :Java 1.6.\n" + + "1.7 :Java 1.7.\n" + + "1.8 :Java 1.8.\n" + + "9 :Java 1.9.\n" + + "9 :Java 9\n" + + "10 :Java 10\n" + + "11 :Java 11\n" + + "12 :Java 12\n" + + "13 :Java 13", commentResolver.resolveCommentForType(javaVersionDuckType, javaVersionPsiClass) + ) val userTypePsiType = jvmClassHelper.resolveClassToType(userTypePsiClass)!! val userInfoPsiType = jvmClassHelper.resolveClassToType(userInfoPsiClass)!! val userCtrlPsiType = jvmClassHelper.resolveClassToType(userCtrlPsiClass)!! val javaVersionPsiType = jvmClassHelper.resolveClassToType(javaVersionPsiClass)!! - assertEquals("ADMIN :administration\n" + - "MEM :a person, an animal or a plant\n" + - "GUEST :Anonymous visitor", commentResolver.resolveCommentForType(userTypePsiType, userTypePsiClass)) + assertEquals( + "1 :administration\n" + + "2 :a person, an animal or a plant\n" + + "3 :Anonymous visitor", + commentResolver.resolveCommentForType(userTypePsiType, userTypePsiClass) + ) assertEquals(null, commentResolver.resolveCommentForType(userInfoPsiType, userInfoPsiClass)) assertEquals(null, commentResolver.resolveCommentForType(userCtrlPsiType, userCtrlPsiClass)) - assertEquals("0.9 :The Java version reported by Android. This is not an official Java version number.\n" + - "1.1 :Java 1.1.\n" + - "1.2 :Java 1.2.\n" + - "1.3 :Java 1.3.\n" + - "1.4 :Java 1.4.\n" + - "1.5 :Java 1.5.\n" + - "1.6 :Java 1.6.\n" + - "1.7 :Java 1.7.\n" + - "1.8 :Java 1.8.\n" + - "9 :Java 1.9.\n" + - "9 :Java 9\n" + - "10 :Java 10\n" + - "11 :Java 11\n" + - "12 :Java 12\n" + - "13 :Java 13", commentResolver.resolveCommentForType(javaVersionPsiType, javaVersionPsiClass)) + assertEquals( + "0.9 :The Java version reported by Android. This is not an official Java version number.\n" + + "1.1 :Java 1.1.\n" + + "1.2 :Java 1.2.\n" + + "1.3 :Java 1.3.\n" + + "1.4 :Java 1.4.\n" + + "1.5 :Java 1.5.\n" + + "1.6 :Java 1.6.\n" + + "1.7 :Java 1.7.\n" + + "1.8 :Java 1.8.\n" + + "9 :Java 1.9.\n" + + "9 :Java 9\n" + + "10 :Java 10\n" + + "11 :Java 11\n" + + "12 :Java 12\n" + + "13 :Java 13", commentResolver.resolveCommentForType(javaVersionPsiType, javaVersionPsiClass) + ) } diff --git a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/spring/SpringRequestClassExporterTest.kt b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/spring/SpringRequestClassExporterTest.kt index bd34f6f83..59601e5d3 100644 --- a/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/spring/SpringRequestClassExporterTest.kt +++ b/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/spring/SpringRequestClassExporterTest.kt @@ -279,7 +279,7 @@ internal class SpringRequestClassExporterTest : PluginContextLightCodeInsightFix assertEquals("/test/return/result/enum", request.path.toString()) assertEquals("GET", request.method) assertEquals( - "{\"code\":0,\"@required\":{\"code\":false,\"msg\":false,\"data\":false},\"@comment\":{\"code\":\"response code\",\"msg\":\"message\",\"data\":\"response data\\nADMIN :administration\\nMEM :a person, an animal or a plant\\nGUEST :Anonymous visitor\"},\"msg\":\"\",\"data\":\"\"}", + "{\"code\":0,\"@required\":{\"code\":false,\"msg\":false,\"data\":false},\"@comment\":{\"code\":\"response code\",\"msg\":\"message\",\"data\":\"response data\",\"data@options\":[{\"value\":\"ADMIN\",\"desc\":\"administration\"},{\"value\":\"MEM\",\"desc\":\"a person, an animal or a plant\"},{\"value\":\"GUEST\",\"desc\":\"Anonymous visitor\"}]},\"msg\":\"\",\"data\":\"\"}", request.response!![0].body.toJson() ) assertNull(request.response!![0].bodyDesc) @@ -531,7 +531,7 @@ internal class SpringRequestClassExporterTest : PluginContextLightCodeInsightFix assertEquals("/test/return/result/enum", request.path.toString()) assertEquals("GET", request.method) assertEquals( - "{\"code\":0,\"@required\":{\"code\":false,\"msg\":false,\"data\":false},\"@comment\":{\"code\":\"response code\",\"msg\":\"message\",\"data\":\"response data\\nADMIN :administration\\nMEM :a person, an animal or a plant\\nGUEST :Anonymous visitor\"},\"msg\":\"\",\"data\":\"\"}", + "{\"code\":0,\"@required\":{\"code\":false,\"msg\":false,\"data\":false},\"@comment\":{\"code\":\"response code\",\"msg\":\"message\",\"data\":\"response data\",\"data@options\":[{\"value\":\"ADMIN\",\"desc\":\"administration\"},{\"value\":\"MEM\",\"desc\":\"a person, an animal or a plant\"},{\"value\":\"GUEST\",\"desc\":\"Anonymous visitor\"}]},\"msg\":\"\",\"data\":\"\"}", request.response!![0].body.toJson() ) assertNull(request.response!![0].bodyDesc) diff --git a/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithExpanded.txt b/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithExpanded.txt index 31373aeaf..8b4e7fb6f 100644 --- a/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithExpanded.txt +++ b/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithExpanded.txt @@ -33,10 +33,11 @@ [INFO] before parse method:com.itangcent.api.TestCtrl#returnResultVoid [INFO] after parse method:com.itangcent.api.TestCtrl#returnResultVoid [INFO] before parse method:com.itangcent.api.TestCtrl#returnEnum -[WARN] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum [INFO] after parse method:com.itangcent.api.TestCtrl#returnEnum [INFO] before parse method:com.itangcent.api.TestCtrl#returnResultEnum -[WARN] can not resolve com.itangcent.constant.UserType for com.itangcent.model.Result#data +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.model.Result#data [INFO] after parse method:com.itangcent.api.TestCtrl#returnResultEnum [INFO] before parse method:com.itangcent.api.TestCtrl#returnEnumField [INFO] after parse method:com.itangcent.api.TestCtrl#returnEnumField diff --git a/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithOutExpanded.txt b/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithOutExpanded.txt index 31373aeaf..8b4e7fb6f 100644 --- a/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithOutExpanded.txt +++ b/idea-plugin/src/test/resources/result/com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporterTest.testExportFromTestCtrlWithOutExpanded.txt @@ -33,10 +33,11 @@ [INFO] before parse method:com.itangcent.api.TestCtrl#returnResultVoid [INFO] after parse method:com.itangcent.api.TestCtrl#returnResultVoid [INFO] before parse method:com.itangcent.api.TestCtrl#returnEnum -[WARN] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.api.TestCtrl#returnEnum [INFO] after parse method:com.itangcent.api.TestCtrl#returnEnum [INFO] before parse method:com.itangcent.api.TestCtrl#returnResultEnum -[WARN] can not resolve com.itangcent.constant.UserType for com.itangcent.model.Result#data +[DEBUG] can not resolve com.itangcent.constant.UserType for com.itangcent.model.Result#data [INFO] after parse method:com.itangcent.api.TestCtrl#returnResultEnum [INFO] before parse method:com.itangcent.api.TestCtrl#returnEnumField [INFO] after parse method:com.itangcent.api.TestCtrl#returnEnumField