Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opti: support param.doc for export methodDoc #347

Merged
merged 1 commit into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.itangcent.idea.config
import com.google.inject.Inject
import com.google.inject.Singleton
import com.google.inject.name.Named
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.sqlite.SqliteDataResourceHelper
import com.itangcent.intellij.config.resource.DefaultResourceResolver
import com.itangcent.intellij.config.resource.URLResource
Expand All @@ -11,10 +12,11 @@ import com.itangcent.intellij.file.LocalFileRepository
import java.io.ByteArrayInputStream
import java.io.InputStream
import java.net.URL
import java.net.URLConnection
import java.util.concurrent.TimeUnit

@Singleton
open class MyResourceResolver : DefaultResourceResolver() {
open class CachedResourceResolver : DefaultResourceResolver() {

@Inject
@Named("projectCacheRepository")
Expand Down Expand Up @@ -54,5 +56,12 @@ open class MyResourceResolver : DefaultResourceResolver() {

override val content: String?
get() = loadCache()?.let { String(it, Charsets.UTF_8) }

override fun onConnection(connection: URLConnection) {
ActionContext.getContext()?.instance(SettingBinder::class)
?.tryRead()?.httpTimeOut?.let {
connection.connectTimeout = it * 1000
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.itangcent.common.spi.Setup
import com.itangcent.idea.config.MyResourceResolver
import com.itangcent.idea.config.CachedResourceResolver
import com.itangcent.idea.plugin.script.GroovyActionExtLoader
import com.itangcent.idea.plugin.script.LoggerBuffer
import com.itangcent.idea.plugin.settings.SettingBinder
Expand Down Expand Up @@ -43,7 +43,7 @@ abstract class BasicAnAction : KotlinAnAction {
builder.bind(SettingBinder::class) { it.toInstance(ServiceManager.getService(SettingBinder::class.java).lazy()) }
builder.bind(Logger::class) { it.with(ConfigurableLogger::class).singleton() }
builder.bind(Logger::class, "delegate.logger") { it.with(ConsoleRunnerLogger::class).singleton() }
builder.bind(ResourceResolver::class) { it.with(MyResourceResolver::class).singleton() }
builder.bind(ResourceResolver::class) { it.with(CachedResourceResolver::class).singleton() }

afterBuildActionContext(event, builder)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.itangcent.idea.plugin.api

import com.google.inject.Inject
import com.intellij.psi.*
import com.itangcent.common.utils.KV
import com.itangcent.common.utils.notNullOrBlank
import com.itangcent.common.utils.notNullOrEmpty
import com.itangcent.idea.plugin.api.export.ClassExportRuleKeys
import com.itangcent.idea.plugin.api.export.LinkResolver
import com.itangcent.intellij.config.rule.RuleComputer
import com.itangcent.intellij.config.rule.computer
import com.itangcent.intellij.jvm.*
import com.itangcent.intellij.jvm.element.ExplicitElement
import com.itangcent.intellij.jvm.element.ExplicitMethod
import java.util.*

open class ClassApiExporterHelper {

@Inject
protected val jvmClassHelper: JvmClassHelper? = null

@Inject
protected val ruleComputer: RuleComputer? = null

@Inject
private val docHelper: DocHelper? = null

@Inject
protected val psiClassHelper: PsiClassHelper? = null

@Inject
private val linkExtractor: LinkExtractor? = null

@Inject
private val linkResolver: LinkResolver? = null

@Inject
protected val duckTypeHelper: DuckTypeHelper? = null

fun extractParamComment(psiMethod: PsiMethod): KV<String, Any>? {
val subTagMap = docHelper!!.getSubTagMapOfDocComment(psiMethod, "param")

var methodParamComment: KV<String, Any>? = null
subTagMap.entries.forEach { entry ->
val name: String = entry.key
val value: String? = entry.value
if (methodParamComment == null) methodParamComment = KV.create()
if (value.notNullOrBlank()) {

val options: ArrayList<HashMap<String, Any?>> = ArrayList()
val comment = linkExtractor!!.extract(value, psiMethod, object : AbstractLinkResolve() {

override fun linkToPsiElement(plainText: String, linkTo: Any?): String? {

psiClassHelper!!.resolveEnumOrStatic(plainText, psiMethod, name)
?.let { options.addAll(it) }

return super.linkToPsiElement(plainText, linkTo)
}

override fun linkToClass(plainText: String, linkClass: PsiClass): String? {
return linkResolver!!.linkToClass(linkClass)
}

override fun linkToType(plainText: String, linkType: PsiType): String? {
return jvmClassHelper!!.resolveClassInType(linkType)?.let {
linkResolver!!.linkToClass(it)
}
}

override fun linkToField(plainText: String, linkField: PsiField): String? {
return linkResolver!!.linkToProperty(linkField)
}

override fun linkToMethod(plainText: String, linkMethod: PsiMethod): String? {
return linkResolver!!.linkToMethod(linkMethod)
}

override fun linkToUnresolved(plainText: String): String? {
return plainText
}
})

methodParamComment!![name] = comment ?: ""
if (options.notNullOrEmpty()) {
methodParamComment!!["$name@options"] = options
}
}

}

return methodParamComment
}

fun foreachMethod(cls: PsiClass, handle: (ExplicitMethod) -> Unit) {
duckTypeHelper!!.explicit(cls)
.methods()
.stream()
.filter { !jvmClassHelper!!.isBasicMethod(it.psi().name) }
.filter { !it.psi().hasModifierProperty("static") }
.filter { !it.psi().isConstructor }
.filter { !shouldIgnore(it) }
.forEach(handle)
}

protected open fun shouldIgnore(explicitElement: ExplicitElement<*>): Boolean {
return ruleComputer!!.computer(ClassExportRuleKeys.IGNORE, explicitElement) ?: false
}

protected open fun shouldIgnore(psiElement: PsiElement): Boolean {
return ruleComputer!!.computer(ClassExportRuleKeys.IGNORE, psiElement) ?: false
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.itangcent.common.utils.*
import com.itangcent.idea.plugin.StatusRecorder
import com.itangcent.idea.plugin.Worker
import com.itangcent.idea.plugin.WorkerStatus
import com.itangcent.idea.plugin.api.ClassApiExporterHelper
import com.itangcent.idea.plugin.api.MethodInferHelper
import com.itangcent.idea.plugin.settings.SettingBinder
import com.itangcent.idea.plugin.settings.group.JsonSetting
Expand All @@ -23,7 +24,6 @@ import com.itangcent.intellij.config.rule.computer
import com.itangcent.intellij.context.ActionContext
import com.itangcent.intellij.jvm.*
import com.itangcent.intellij.jvm.duck.DuckType
import com.itangcent.intellij.jvm.element.ExplicitElement
import com.itangcent.intellij.jvm.element.ExplicitMethod
import com.itangcent.intellij.jvm.element.ExplicitParameter
import com.itangcent.intellij.logger.Logger
Expand Down Expand Up @@ -106,6 +106,9 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
@Inject
private val contextSwitchListener: ContextSwitchListener? = null

@Inject
private lateinit var classApiExporterHelper: ClassApiExporterHelper

override fun export(cls: Any, docHandle: DocHandle, completedHandle: CompletedHandle): Boolean {
if (cls !is PsiClass) {
completedHandle(cls)
Expand All @@ -132,7 +135,7 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {

processClass(cls, kv)

foreachMethod(cls) { explicitMethod ->
classApiExporterHelper.foreachMethod(cls) { explicitMethod ->
val method = explicitMethod.psi()
if (isApi(method) && methodFilter?.checkMethod(method) != false) {
try {
Expand Down Expand Up @@ -163,10 +166,6 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
return ruleComputer!!.computer(ClassExportRuleKeys.IGNORE, psiElement) ?: false
}

open protected fun shouldIgnore(explicitElement: ExplicitElement<*>): Boolean {
return ruleComputer!!.computer(ClassExportRuleKeys.IGNORE, explicitElement) ?: false
}

private fun exportMethodApi(
psiClass: PsiClass, method: ExplicitMethod, kv: KV<String, Any?>,
docHandle: DocHandle
Expand Down Expand Up @@ -401,78 +400,13 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
return docHelper!!.getAttrOfDocComment(method)
}

private fun extractParamComment(psiMethod: PsiMethod): KV<String, Any>? {
val subTagMap = docHelper!!.getSubTagMapOfDocComment(psiMethod, "param")

var methodParamComment: KV<String, Any>? = null
subTagMap.entries.forEach { entry ->
val name: String = entry.key
val value: String? = entry.value
if (methodParamComment == null) methodParamComment = KV.create()
if (value.notNullOrBlank()) {

val options: ArrayList<HashMap<String, Any?>> = ArrayList()
val comment = linkExtractor!!.extract(value, psiMethod, object : AbstractLinkResolve() {

override fun linkToPsiElement(plainText: String, linkTo: Any?): String? {

psiClassHelper!!.resolveEnumOrStatic(plainText, psiMethod, name)
?.let { options.addAll(it) }

return super.linkToPsiElement(plainText, linkTo)
}

override fun linkToClass(plainText: String, linkClass: PsiClass): String? {
return linkResolver!!.linkToClass(linkClass)
}

override fun linkToType(plainText: String, linkType: PsiType): String? {
return jvmClassHelper!!.resolveClassInType(linkType)?.let {
linkResolver!!.linkToClass(it)
}
}

override fun linkToField(plainText: String, linkField: PsiField): String? {
return linkResolver!!.linkToProperty(linkField)
}

override fun linkToMethod(plainText: String, linkMethod: PsiMethod): String? {
return linkResolver!!.linkToMethod(linkMethod)
}

override fun linkToUnresolved(plainText: String): String? {
return plainText
}
})

methodParamComment!![name] = comment ?: ""
if (options.notNullOrEmpty()) {
methodParamComment!!["$name@options"] = options
}
}

}
return methodParamComment
}

private fun foreachMethod(cls: PsiClass, handle: (ExplicitMethod) -> Unit) {
duckTypeHelper!!.explicit(cls)
.methods()
.stream()
.filter { !jvmClassHelper!!.isBasicMethod(it.psi().name) }
.filter { !it.psi().hasModifierProperty("static") }
.filter { !it.psi().isConstructor }
.filter { !shouldIgnore(it) }
.forEach(handle)
}

private fun processMethodParameters(method: ExplicitMethod, request: Request) {

val params = method.getParameters()

if (params.isNotEmpty()) {

val paramDocComment = extractParamComment(method.psi())
val paramDocComment = classApiExporterHelper.extractParamComment(method.psi())

val parsedParams: ArrayList<ExplicitParameterInfo> = ArrayList()
for (param in params) {
Expand Down Expand Up @@ -683,22 +617,22 @@ abstract class AbstractRequestClassExporter : ClassExporter, Worker {
return null
}

protected fun parseResponseBody(psiType: DuckType?, fromRule: Boolean, method: ExplicitMethod): Any? {
protected fun parseResponseBody(duckType: DuckType?, fromRule: Boolean, method: ExplicitMethod): Any? {

if (psiType == null) {
if (duckType == null) {
return null
}

return when {
fromRule -> psiClassHelper!!.getTypeObject(psiType, method.psi(),
fromRule -> psiClassHelper!!.getTypeObject(duckType, method.psi(),
jsonSetting!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
needInfer() && (!duckTypeHelper!!.isQualified(psiType) ||
jvmClassHelper!!.isInterface(psiType)) -> {
needInfer() && (!duckTypeHelper!!.isQualified(duckType) ||
jvmClassHelper!!.isInterface(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(psiType, method.psi(),
else -> psiClassHelper!!.getTypeObject(duckType, method.psi(),
jsonSetting!!.jsonOptionForOutput(JsonOption.READ_COMMENT))
}
}
Expand Down
Loading