diff --git a/buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock index f1149acc..ecbeea9c 100755 Binary files a/buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/buildSrc/build/libs/buildSrc.jar b/buildSrc/build/libs/buildSrc.jar index faf37d2a..fa847b33 100644 Binary files a/buildSrc/build/libs/buildSrc.jar and b/buildSrc/build/libs/buildSrc.jar differ diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/build.gradle.kts b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/build.gradle.kts new file mode 100644 index 00000000..f42f46e9 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/build.gradle.kts @@ -0,0 +1,12 @@ +dependencies { + implementation(project(":kotlin-spring-framework-project:kotlin-spring-core")) + implementation(project(":kotlin-spring-framework-project:kotlin-spring-beans")) + compileOnly(project(":kotlin-spring-framework-project:kotlin-spring-aop")) + implementation(project(":kotlin-spring-framework-project:kotlin-spring-context")) + implementation(project(":kotlin-spring-framework-project:kotlin-spring-jcl")) + implementation("org.slf4j:slf4j-api:$slf4jApiVersion") + implementation(project(":kotlin-spring-framework-project:kotlin-spring-web")) + implementation(project(":kotlin-spring-boot-project:kotlin-spring-boot")) + implementation(project(":kotlin-spring-boot-project:kotlin-spring-boot-autoconfigure")) + implementation("org.slf4j:slf4j-api:$slf4jApiVersion") +} diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/BistouryProxyApplication.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/BistouryProxyApplication.kt new file mode 100644 index 00000000..c6d8ef19 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/BistouryProxyApplication.kt @@ -0,0 +1,19 @@ +package com.wanna.debugger.bistoury.instrument.proxy + +import com.wanna.boot.autoconfigure.SpringBootApplication +import com.wanna.boot.runSpringApplication + +/** + * Bistoury Proxy Application + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +@SpringBootApplication(proxyBeanMethods = false) +open class BistouryProxyApplication + +fun main(vararg args: String) { + var applicationContext = runSpringApplication(*args) + println(applicationContext) +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Connection.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Connection.kt new file mode 100644 index 00000000..8b5f80d3 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Connection.kt @@ -0,0 +1,13 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate + +/** + * 描述了前端(UI)-Proxy, 或者是Proxy-Agent之间的数据传输的连接 + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface Connection { + + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/DefaultSession.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/DefaultSession.kt new file mode 100644 index 00000000..b29d942f --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/DefaultSession.kt @@ -0,0 +1,28 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate + +import com.wanna.debugger.bistoury.instrument.proxy.communicate.agent.AgentConnection +import com.wanna.debugger.bistoury.instrument.proxy.communicate.ui.UIConnection + +/** + * Session + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +open class DefaultSession : Session { + + + + override fun getSessionId(): String { + TODO("Not yet implemented") + } + + override fun getUIConnection(): UIConnection { + TODO("Not yet implemented") + } + + override fun getAgentConnection(): AgentConnection { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/NettyServer.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/NettyServer.kt new file mode 100644 index 00000000..ddb10077 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/NettyServer.kt @@ -0,0 +1,21 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate + +/** + * NettyServer + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface NettyServer { + + /** + * 启动NettyServer + */ + fun start() + + /** + * 关闭NettyServer + */ + fun stop() +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Session.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Session.kt new file mode 100644 index 00000000..18248f79 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/Session.kt @@ -0,0 +1,35 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate + +import com.wanna.debugger.bistoury.instrument.proxy.communicate.agent.AgentConnection +import com.wanna.debugger.bistoury.instrument.proxy.communicate.ui.UIConnection + +/** + * 描述了从前端(UI)-Proxy-Agent的会话关系 + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface Session { + + /** + * 获取SessionId + * + * @return sessionId + */ + fun getSessionId(): String + + /** + * 获取UIConnection(UI-Proxy之间的连接) + * + * @return UIConnection + */ + fun getUIConnection(): UIConnection + + /** + * 获取AgentConnection(Proxy-Agent之间的连接) + * + * @return AgentConnection + */ + fun getAgentConnection(): AgentConnection +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/SessionManager.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/SessionManager.kt new file mode 100644 index 00000000..9609e7ec --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/SessionManager.kt @@ -0,0 +1,29 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate + +import com.wanna.debugger.bistoury.instrument.proxy.communicate.ui.UIConnection + +/** + * Session的Manager + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface SessionManager { + + /** + * 根据sessionId去获取Session + * + * @param sessionId sessionId + * @return 获取到的Session(不存在该Session的话, 返回null) + */ + fun getSession(sessionId: String): Session? + + /** + * 获取单个UIConnection对应的所有的Session + * + * @param uiConnection UIConnection + * @return 获取到的所有的Session列表 + */ + fun getSessionsByUIConnection(uiConnection: UIConnection): Set +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/agent/AgentConnection.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/agent/AgentConnection.kt new file mode 100644 index 00000000..f7d7b32b --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/agent/AgentConnection.kt @@ -0,0 +1,14 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate.agent + +import com.wanna.debugger.bistoury.instrument.proxy.communicate.Connection + +/** + * AgentConnection + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface AgentConnection : Connection { + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/UIConnection.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/UIConnection.kt new file mode 100644 index 00000000..fe94ebc9 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/UIConnection.kt @@ -0,0 +1,14 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate.ui + +import com.wanna.debugger.bistoury.instrument.proxy.communicate.Connection + +/** + * UIConnection + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +interface UIConnection : Connection { + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/command/CommunicateCommand.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/command/CommunicateCommand.kt new file mode 100644 index 00000000..b0df24bd --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/communicate/ui/command/CommunicateCommand.kt @@ -0,0 +1,12 @@ +package com.wanna.debugger.bistoury.instrument.proxy.communicate.ui.command + +/** + * UI和Proxy之间沟通的命令 + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +class CommunicateCommand { + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/IdGenerator.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/IdGenerator.kt new file mode 100644 index 00000000..d7ec6701 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/IdGenerator.kt @@ -0,0 +1,18 @@ +package com.wanna.debugger.bistoury.instrument.proxy.generator + +/** + * ID生成器 + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +interface IdGenerator { + + /** + * 生成ID + * + * @return 生成的ID + */ + fun generateId(): String +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/SessionIdGenerator.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/SessionIdGenerator.kt new file mode 100644 index 00000000..9af22c79 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/generator/SessionIdGenerator.kt @@ -0,0 +1,27 @@ +package com.wanna.debugger.bistoury.instrument.proxy.generator + +import com.wanna.framework.context.stereotype.Component +import java.util.concurrent.atomic.AtomicInteger + +/** + * UI-Proxy-Agent之间建立的Session的IdGenerator + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +@Component +class SessionIdGenerator : IdGenerator { + + companion object { + /** + * 自增ID + */ + @JvmStatic + private val AUTO_INCREMENT_ID = AtomicInteger() + } + + override fun generateId(): String { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/startup/NettyServerManager.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/startup/NettyServerManager.kt new file mode 100644 index 00000000..dd6a77a8 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-proxy/src/main/kotlin/com/wanna/debugger/bistoury/instrument/proxy/startup/NettyServerManager.kt @@ -0,0 +1,15 @@ +package com.wanna.debugger.bistoury.instrument.proxy.startup + +import com.wanna.framework.context.stereotype.Component + +/** + * NettyServer Manager + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/22 + */ +@Component +class NettyServerManager { + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentDecoder.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentDecoder.kt new file mode 100644 index 00000000..10d20933 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentDecoder.kt @@ -0,0 +1,11 @@ +package com.wanna.debugger.bistoury.instrument.remoting.codec + +/** + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +open class AgentDecoder { + +} \ No newline at end of file diff --git a/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentEncoder.kt b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentEncoder.kt new file mode 100644 index 00000000..01dc9058 --- /dev/null +++ b/kotlin-debugger-project/kotlin-debugger-bistoury/kotlin-debugger-bistoury-remoting/src/main/kotlin/com/wanna/debugger/bistoury/instrument/remoting/codec/AgentEncoder.kt @@ -0,0 +1,11 @@ +package com.wanna.debugger.bistoury.instrument.remoting.codec + +/** + * + * @author jianchao.jia + * @version v1.0 + * @date 2023/6/24 + */ +open class AgentEncoder { + +} \ No newline at end of file diff --git a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/InjectionPoint.kt b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/InjectionPoint.kt index 1fc70905..8e358369 100755 --- a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/InjectionPoint.kt +++ b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/InjectionPoint.kt @@ -1,12 +1,19 @@ package com.wanna.framework.beans.factory import com.wanna.framework.core.MethodParameter +import com.wanna.framework.lang.Nullable import java.lang.reflect.Field /** * 这是一个依赖的注入点, 它的常见实现是DependencyDescriptor + * + * @param field 字段 + * @param parameter 方法参数 */ -open class InjectionPoint(private val field: Field? = null, private val parameter: MethodParameter? = null) { +open class InjectionPoint( + private val field: Field? = null, + private val parameter: MethodParameter? = null +) { /** * 获取方法参数/构造器参数/字段上的注解列表 */ @@ -22,7 +29,11 @@ open class InjectionPoint(private val field: Field? = null, private val paramete /** * 获取指定的注解, 如果是一个方法参数, 那么从方法参数当中获取注解; 如果是一个字段, 从字段当中获取注解 + * + * @param annotationClass 要去进行寻找的注解类型 + * @return 寻找到的注解, 如果没有合适的, 那么return null */ + @Nullable open fun getAnnotation(annotationClass: Class): T? { if (field != null) { return field.getAnnotation(annotationClass) @@ -33,11 +44,28 @@ open class InjectionPoint(private val field: Field? = null, private val paramete return null } + /** + * 获取到字段, 如果描述的是一个方法参数, 那么return null + * + * @return Field + */ + @Nullable open fun getField(): Field? = this.field - /** * 获取方法参数, 如果这描述的是一个字段, 那么return null + * + * @return MethodParameter */ + @Nullable open fun getMethodParameter(): MethodParameter? = this.parameter + + /** + * 获取方法参数MethodParameter + * + * @return MethodParameter + */ + open fun obtainMethodParameter(): MethodParameter { + return this.parameter ?: throw IllegalStateException("MethodParameter cannot be null") + } } \ No newline at end of file diff --git a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DefaultListableBeanFactory.kt b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DefaultListableBeanFactory.kt index bfb954d9..8565182e 100755 --- a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DefaultListableBeanFactory.kt +++ b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DefaultListableBeanFactory.kt @@ -765,13 +765,23 @@ open class DefaultListableBeanFactory : ConfigurableListableBeanFactory, BeanDef } /** - * 多个元素的DependencyDescriptor + * 增加泛型参数的嵌套级别的DependencyDescriptor, 包装一层, 修改当前DependencyDescriptor的嵌套级别 + * + * @param descriptor 待增加嵌套级别的依赖描述符 + */ + private open class NestedDependencyDescriptor(descriptor: DependencyDescriptor) : DependencyDescriptor(descriptor) { + init { + // 增加嵌套级别 + this.increaseNestingLevel() + } + } + + /** + * 需要去注入多个元素的DependencyDescriptor(Map/List/...) * * @param descriptor 原始的Descriptor */ - private class MultiElementDescriptor(descriptor: DependencyDescriptor) : DependencyDescriptor( - descriptor.getField(), descriptor.getMethodParameter(), descriptor.isRequired(), descriptor.isEager() - ) + private class MultiElementDescriptor(descriptor: DependencyDescriptor) : NestedDependencyDescriptor(descriptor) /** * 解析多个Bean的情况, 比如Collection/Map/Array等类型的依赖的解析, 有可能会需要用到Converter去完成类型的转换 diff --git a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DependencyDescriptor.kt b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DependencyDescriptor.kt index 31efd465..9c904e38 100755 --- a/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DependencyDescriptor.kt +++ b/kotlin-spring-framework-project/kotlin-spring-beans/src/main/kotlin/com/wanna/framework/beans/factory/support/DependencyDescriptor.kt @@ -5,14 +5,16 @@ import com.wanna.framework.beans.factory.InjectionPoint import com.wanna.framework.core.MethodParameter import com.wanna.framework.core.ParameterNameDiscoverer import com.wanna.framework.core.ResolvableType +import com.wanna.framework.lang.Nullable import java.lang.reflect.Field +import java.lang.reflect.ParameterizedType import java.lang.reflect.Type /** * 这是一个依赖的描述符, 可以描述一个方法的参数, 或者是一个字段, 当然, 也可以是一个构造器的参数也是可以的 * 在Spring当中需要去进行依赖的解析时, 就会将依赖的相关信息都封装成为一个DependencyDescriptor, 方便BeanFactory当中可以对依赖去进行解析工作 * - * @param required 该依赖是否是必须的? + * @param required 该依赖是否是必须的? * @param eager 解析依赖的时候, 是否允许依赖被eagerInit(比如FactoryBean被提前创建) */ open class DependencyDescriptor protected constructor( @@ -29,46 +31,93 @@ open class DependencyDescriptor protected constructor( descriptor.getMethodParameter(), descriptor.required, descriptor.eager - ) + ) { + // copy declaringClass + this.declaringClass = descriptor.declaringClass + // copy methodName + this.methodName = descriptor.methodName + + // copy parameterTypes + this.parameterTypes = descriptor.parameterTypes + // copy parameterIndex + this.parameterIndex = descriptor.parameterIndex - constructor(field: Field?, required: Boolean) : this(field, null, required) - constructor(field: Field?, required: Boolean, eager: Boolean) : this(field, null, required, eager) - constructor(parameter: MethodParameter?, required: Boolean) : this(null, parameter, required) - constructor(parameter: MethodParameter?, required: Boolean, eager: Boolean) : this(null, parameter, required, eager) + // copy fieldName + this.fieldName = descriptor.fieldName + // copy containingClass + this.containingClass = descriptor.containingClass + // copy nestedLevel + this.nestingLevel = descriptor.nestingLevel + } + + constructor(@Nullable field: Field?, required: Boolean) : this(field, null, required) + constructor(@Nullable field: Field?, required: Boolean, eager: Boolean) : this(field, null, required, eager) + constructor(@Nullable parameter: MethodParameter?, required: Boolean) : this(null, parameter, required) + constructor(@Nullable parameter: MethodParameter?, required: Boolean, eager: Boolean) : this( + null, + parameter, + required, + eager + ) + + /** + * 字段/方法参数被定义的类 + */ private var declaringClass: Class<*>? = if (field != null) field.declaringClass else parameter?.getDeclaringClass() - // 字段名(描述的是一个字段时才生效) + /** + * 字段名(描述的是一个字段时才生效) + */ private var fieldName: String? = field?.name - // 方法的参数类型列表(描述的是一个参数时才生效) + /** + * 方法的参数类型列表(描述的是一个参数时才生效) + */ private var parameterTypes: Array>? = parameter?.getParameterTypes() - // 方法名(描述的是一个方法时才生效) + /** + * 方法名(描述的是一个方法时才生效) + */ private var methodName: String? = parameter?.getMethod()?.name - // 参数所在的索引, 默认为0 + /** + * 方法参数所在的索引, 默认为0 + */ private var parameterIndex: Int = parameter?.getParameterIndex() ?: 0 - // containingClass + /** + * containingClass(方法参数对应的方法所在的类的具体实现类, containingClass可能为declaringClass的子类) + */ private var containingClass: Class<*>? = parameter?.getContainingClass() - // 参数名发现器 + /** + * 参数名发现器 + * + * @see initParameterNameDiscoverer + */ private var parameterNameDiscoverer: ParameterNameDiscoverer? = null - // 当前泛型的层级(不会实现...) + /** + * 当前泛型的嵌套层级 + * + * @see increaseNestingLevel + */ private var nestingLevel: Int = 1 - // 可以解析的类型 + /** + * 可以解析的类型ResolvableType(缓存, 使用时自动根据Field/MethodParameter去解析) + * + * @see getResolvableType + */ private var resolvableType: ResolvableType? = null - /** * 初始化参数名发现器 * * @param parameterNameDiscoverer 要指定的ParameterNameDiscoverer; 可以为null */ - open fun initParameterNameDiscoverer(parameterNameDiscoverer: ParameterNameDiscoverer?) { + open fun initParameterNameDiscoverer(@Nullable parameterNameDiscoverer: ParameterNameDiscoverer?) { if (parameterNameDiscoverer != null) { this.parameterNameDiscoverer = parameterNameDiscoverer } @@ -94,6 +143,8 @@ open class DependencyDescriptor protected constructor( /** * 获取泛型的类型, 如果是一个方法参数, 那么获取方法参数的泛型; 如果是一个字段, 那么获取字段的泛型类型 + * + * @return genericType */ open fun getGenericType(): Type { val parameter = getMethodParameter() @@ -107,39 +158,67 @@ open class DependencyDescriptor protected constructor( return null!! } - // 获取containingClass + /** + * 获取containingClass(方法参数所定义的方法所在的类) + * + * @return containingClass + */ open fun getContainingClass(): Class<*>? = containingClass - open fun setContainingClass(containingClass: Class<*>?) { + open fun setContainingClass(@Nullable containingClass: Class<*>?) { this.containingClass = containingClass } - // 获取参数所在的索引, 如果描述的是字段的话, 值为0 + /** + * 获取参数所在的索引, 如果描述的是字段的话, 值为0 + * + * @return 参数索引index + */ open fun getParameterIndex(): Int { return parameterIndex } - // 如果描述的是一个方法的话, 返回方法名, 如果描述的不是一个方法的话, 返回null + /** + * 如果描述的是一个方法的话, 返回方法名, 如果描述的不是一个方法的话, 返回null + * + * @return methodName(如果描述的是字段的话, 值为null) + */ open fun getMethodName(): String? { return methodName } - // 获取方法/字段/构造器所在的定义的类 + /** + * 获取方法/字段/构造器所在的定义的类 + * + * @return 方法/字段/构造器所在的定义的类 + */ open fun getDeclaringClass(): Class<*> { return declaringClass!! } - // 获取方法的参数类型列表, 如果描述的不是一个方法, 那么return null + /** + * 获取方法的参数类型列表, 如果描述的不是一个方法, 那么return null + * + * @return 参数类型列表 + */ open fun getParameterTypes(): Array>? { return parameterTypes } - // 获取字段名, 如果它根本不是一个字段, return null + /** + * 获取字段名, 如果它根本不是一个字段, return null + * + * @return fieldName(or null) + */ open fun getFieldName(): String? { return fieldName } - // 该依赖, 是否是必要的? (required=true? ) + /** + * 该依赖, 是否是必要的? (required=true? ) + * + * @return required? + */ open fun isRequired(): Boolean { if (!required) { return false @@ -149,19 +228,51 @@ open class DependencyDescriptor protected constructor( open fun isEager(): Boolean = eager + /** + * 获取依赖的名称 + * + * @return 依赖名称(字段名/方法参数名) + */ + @Nullable + open fun getDependencyName(): String? { + return getField()?.name ?: obtainMethodParameter().getParameterName() + } + /** * 返回依赖的类型, 如果是字段返回字段类型, 如果是方法参数返回方法参数的类型 + * + * @return 待解析的依赖类型 */ open fun getDependencyType(): Class<*> { - val parameter = getMethodParameter() + // 模拟com.wanna.framework.core.MethodParameter.getNestedParameterType, 去解析嵌套的泛型参数类型 val field = getField() - if (parameter != null) { - return parameter.getParameterType() - } if (field != null) { - return field.type + // 嵌套层级>1, 需要解析嵌套的泛型参数类型 + if (this.nestingLevel > 1) { + var type = field.genericType + for (i in 2..nestingLevel) { + if (type is ParameterizedType) { + val args = type.actualTypeArguments + type = args[args.size - 1] + } + } + if (type is Class<*>) { + return type + } else if (type is ParameterizedType) { + val rawType = type.rawType + if (rawType is Class<*>) { + return rawType + } + } + return Any::class.java + + // 如果嵌套层级为1, 那么直接返回fieldType + } else { + return field.type + } + } else { + return obtainMethodParameter().getNestedParameterType() } - return null!! } /** @@ -176,14 +287,29 @@ open class DependencyDescriptor protected constructor( } /** - * 获取到该依赖描述符的可以解析的类型 + * 增加泛型参数的嵌套级别, 比如List, 最开始在List, 嵌套层级增加之后就在String... + */ + open fun increaseNestingLevel() { + // nestingLevel++, 为了获取resolvableType时可以到深层次嵌套的泛型参数 + this.nestingLevel++ + // 把resolvableType去重置为null, 懒加载机制, 在调用getResolvableType方法时, 根据nestedLevel去进行重新初始化 + this.resolvableType = null + // 让methodParameter的泛型嵌套层级++ + this.getMethodParameter()?.nested() + } + + /** + * 获取到该依赖描述符的可以解析的类型ResolvableType, 自动根据Field/MethodParameter去进行解析 + * + * @return 依赖描述符的ResolvableType */ open fun getResolvableType(): ResolvableType { val field = getField() var resolvableType = this.resolvableType if (resolvableType == null) { if (field != null) { - resolvableType = ResolvableType.forField(field) + // 为当前的嵌套级别的泛型参数, 去构建ResolvableType + resolvableType = ResolvableType.forField(field, nestingLevel, this.containingClass) } else { resolvableType = ResolvableType.forMethodParameter(getMethodParameter()!!) } diff --git a/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/MethodParameter.kt b/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/MethodParameter.kt index 48c5e60c..33521855 100755 --- a/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/MethodParameter.kt +++ b/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/MethodParameter.kt @@ -1,6 +1,7 @@ package com.wanna.framework.core import com.wanna.framework.core.annotation.AnnotatedElementUtils +import com.wanna.framework.lang.Nullable import java.lang.reflect.* /** @@ -12,27 +13,45 @@ import java.lang.reflect.* * * @param executable 方法/字段/构造器 * @param parameterIndex 参数的index, 必须介于[-1, parameterCount-1]之间, 并且index=-1代表描述的是方法的返回值 + * @param containingClass containingClass, 指定的方法的具体实现类, 如果不给这个参数的话, 那么认为containingClass就是declaringClass + * @param nestingLevel 方法参数的嵌套层级, 用于解析泛型, 例如Map在指定nestingLevel=2的情况下, 可以获取到内部的泛型参数 + * @param typeIndexesPerLevel 嵌套层级解析泛型参数时, 需要使用哪个位置的泛型参数 */ open class MethodParameter( private var executable: Executable, private var parameterIndex: Int, private var containingClass: Class<*>?, - private var nestingLevel: Int = 1 + private var nestingLevel: Int = 1, + private var typeIndexesPerLevel: MutableMap? ) { - - constructor(executable: Executable, parameterIndex: Int) : this(executable, parameterIndex, null, 1) + constructor(executable: Executable, parameterIndex: Int) : this(executable, parameterIndex, null, 1, null) constructor(executable: Executable, parameterIndex: Int, nestingLevel: Int) : this( executable, parameterIndex, null, - nestingLevel + nestingLevel, + null ) constructor(executable: Executable, parameterIndex: Int, containingClass: Class<*>?) : this( executable, parameterIndex, containingClass, - 1 + 1, + null + ) + + /** + * 对外提供一个用于copy的MethodParameter构造器 + * + * @param original 原始的待进行copy的MethodParameter + */ + constructor(original: MethodParameter) : this( + original.executable, + original.parameterIndex, + original.containingClass, + original.nestingLevel, + original.typeIndexesPerLevel ) init { @@ -42,9 +61,16 @@ open class MethodParameter( } } - // 参数名发现器, 提供该方法/构造器当中的方法的参数名列表的获取 + /** + * 参数名发现器, 提供该方法/构造器当中的方法的参数名列表的获取 + */ private var parameterNameDiscoverer: ParameterNameDiscoverer? = null + /** + * 嵌套一层的MethodParameter(常用, 做一层缓存) + */ + private var nestedMethodParameter: MethodParameter? = null + /** * 初始化参数名发现器(Kotlin反射/标准反射/ASM三种方式) * @@ -63,6 +89,28 @@ open class MethodParameter( return executable.parameters[parameterIndex].annotations } + /** + * 获取原始的typeIndexesPerLevel的Map + * + * @return typeIndexesPerLevel + */ + @Nullable + open fun getOriginTypeIndexesPerLevel(): Map? { + return typeIndexesPerLevel + } + + /** + * 获取懒加载的typeIndexesPerLevel Map, 如果之前不存在的话, 那么构建一个空的Map + * + * @return typeIndexesPerLevel + */ + open fun getTypeIndexesPerLevel(): MutableMap { + if (this.typeIndexesPerLevel == null) { + this.typeIndexesPerLevel = LinkedHashMap(4) + } + return this.typeIndexesPerLevel!! + } + /** * 获取描述的方法/构造器的参数上的注解列表 * @@ -94,7 +142,7 @@ open class MethodParameter( * @return 如果方法上标注了该注解, 那么return true; 否则return false */ open fun hasMethodAnnotation(annotationClass: Class): Boolean { - return AnnotatedElementUtils.hasAnnotation(this.executable, annotationClass); + return AnnotatedElementUtils.hasAnnotation(this.executable, annotationClass) } /** @@ -120,6 +168,34 @@ open class MethodParameter( return executable.parameterTypes[parameterIndex] } + /** + * 获取嵌套的泛型的参数类型(如果nestingLevel=1, 那么返回参数类型; 如果nestingLevel>1, 那么需要递归解析嵌套的参数类型) + * + * @return 嵌套的泛型的参数类型 + */ + open fun getNestedParameterType(): Class<*> { + if (this.nestingLevel > 1) { + var type = getGenericParameterType() + for (i in 2..nestingLevel) { + if (type is ParameterizedType) { + val args = type.actualTypeArguments + type = args[getTypeIndexesPerLevel()[i] ?: (args.size - 1)] + } + } + if (type is Class<*>) { + return type + } else if (type is ParameterizedType) { + val rawType = type.rawType + if (rawType is Class<*>) { + return rawType + } + } + return Any::class.java + } else { + return getParameterType() + } + } + /** * 获取方法参数(来自jdk的Parameter)对象, 将其暴露给使用者 */ @@ -145,7 +221,7 @@ open class MethodParameter( } /** - * 该方法/构造器, 被定义在哪个类当中? + * 该方法/构造器, 被定义在哪个类当中? * * @return 方法/构造器所被定义的类 */ @@ -154,7 +230,9 @@ open class MethodParameter( } /** - * 获取包含的类 + * 获取包含的类, 也就是方法的具体实现类(如果有指定containingClass, 那么使用自定义的; 如果没有自定义, 那么使用declaringClass作为containingClass) + * + * @return 方法的具体实现类 */ open fun getContainingClass(): Class<*> { return containingClass ?: getDeclaringClass() @@ -232,8 +310,58 @@ open class MethodParameter( return null } - override fun toString(): String { - return "MethodParameter(executable=$executable, parameterIndex=$parameterIndex, containingClass=$containingClass, nestingLevel=$nestingLevel)" + /** + * 获取当前方法参数, 嵌套一层的泛型方法参数 + * + * @return 嵌套一层的泛型参数 + */ + open fun nested(): MethodParameter { + return nested(null) + } + + /** + * 获取当前方法参数, 嵌套一层的泛型方法参数 + * + * @param typeIndex 该层级要使用哪个位置的泛型参数? 不传默认取最后一个 + * @return 嵌套一层的泛型参数 + */ + open fun nested(@Nullable typeIndex: Int?): MethodParameter { + var nestedParam = this.nestedMethodParameter + // 如果type==null, 缓存起来单层嵌套的MethodParameter + if (nestedParam != null && typeIndex == null) { + return nestedParam + } + nestedParam = nested(this.nestingLevel + 1, typeIndex) + if (typeIndex == null) { + nestedMethodParameter = nestedParam + } + return nestedParam + } + + /** + * 根据当前方法参数, 以及嵌套层级信息, 重新去构建一个MethodParameter + * + * @param nestingLevel 最终的嵌套层级 + * @param typeIndex 该嵌套层级的泛型参数, 需要使用哪个位置的泛型, 指定泛型参数index? + */ + open fun nested(nestingLevel: Int, typeIndex: Int?): MethodParameter { + val copy = clone() + + // 修改嵌套层级 + copy.nestingLevel = nestingLevel + // copy typeIndexesPerLevel + if (this.typeIndexesPerLevel != null) { + copy.typeIndexesPerLevel = LinkedHashMap(this.typeIndexesPerLevel) + } + if (typeIndex != null) { + copy.getTypeIndexesPerLevel()[nestingLevel] = typeIndex + } + + return copy + } + + open fun clone(): MethodParameter { + return MethodParameter(this) } @@ -242,7 +370,7 @@ open class MethodParameter( * 提供静态方法, 为Executable去构建MethodParameter * * @param executable 方法/构造器 - * @param parameterIndex 当前参数位于该方法/构造器的第几个位置? + * @param parameterIndex 当前参数位于该方法/构造器的第几个位置? * @return 为该方法参数构建好的MethodParameter对象 */ @JvmStatic diff --git a/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/ResolvableType.kt b/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/ResolvableType.kt index 31582c2e..4294143d 100755 --- a/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/ResolvableType.kt +++ b/kotlin-spring-framework-project/kotlin-spring-core/src/main/kotlin/com/wanna/framework/core/ResolvableType.kt @@ -1,5 +1,6 @@ package com.wanna.framework.core +import com.wanna.framework.lang.Nullable import java.io.Serializable import java.lang.reflect.* @@ -148,6 +149,59 @@ open class ResolvableType { return this.resolved ?: fallback } + /** + * 获取嵌套层级的Type信息 + * + * * 1.比如针对List>这种情况, nestingLevel=1将会获取到List, + * nestingLevel=2将会获取到Set, nestingLevel=3将会获取到String. + * * 2.针对String[]这种情况, nestingLevel=1可以获取到String[], nestingLevel=2可以获取到String. + * * 3.某些层级可能存在有多个泛型, 比如Map, 这种情况获取到的是最后一个泛型, 也就是Integer + * * 4.如果当前类没有泛型, 那么也支持从父类当中去进行寻找泛型... + * + * @param nestingLevel 要获取泛型的具体嵌套层级 + * @return 获取到的嵌套层级的泛型(可能为NONE) + */ + open fun getNested(nestingLevel: Int): ResolvableType { + return getNested(nestingLevel, null) + } + + /** + * 获取嵌套层级的Type信息 + * + * * 1.比如针对List>这种情况, nestingLevel=1将会获取到List, + * nestingLevel=2将会获取到Set, nestingLevel=3将会获取到String. + * * 2.针对String[]这种情况, nestingLevel=1可以获取到String[], nestingLevel=2可以获取到String. + * * 3.针对typeIndexesPerLevel, 用于获取获取某个层级(key)需要获取第几个(value)泛型, 比如Map, + * 例如指定value为1, 那么代表要获取到Integer的泛型, value为0, 那么代表要获取到String的泛型. + * 如果typeIndexesPerLevel当中没有指定当前level要使用的泛型, 默认取最后一个泛型去进行计算, 也就是Integer + * * 4.如果当前类没有泛型, 那么也支持从父类当中去进行寻找泛型... + * + * @param nestingLevel 要获取泛型的具体嵌套层级 + * @param typeIndexesPerLevel 某个层级要取第几个泛型? key-层级, value-泛型index + * @return 获取到的嵌套层级的泛型(可能为NONE) + */ + open fun getNested(nestingLevel: Int, typeIndexesPerLevel: Map?): ResolvableType { + var result = this + for (i in 2..nestingLevel) { + // 如果是数组的话, 那么获取它的元素类型, 并消耗一个层级 + if (result.isArray()) { + result = result.getComponentType() + } else { + + // 如果当前result不为NONE, 但是不存在有泛型的话, 那么尝试从superType去进行获取 + while (result != NONE && !result.hasGenerics()) { + result = result.getSuperType() + } + + // 如果typeIndexesPerLevel当中指定了要读取当前层级要使用第几个索引的话 + // 那么取自定义的, 如果没有自定义的话, 那么取默认的层级... + val index = typeIndexesPerLevel?.get(i) ?: (result.getGenerics().size - 1) + result = result.getGeneric(index) + } + } + return result + } + /** * 根据给定的indexes去返回对应的泛型参数的ResolvableType, * 例如Map>, getGeneric(0)将会得到Integer, @@ -456,26 +510,99 @@ open class ResolvableType { @JvmField val EMPTY_TYPES_ARRAY = emptyArray() + /** + * 基于给定的Class, 去包装成为ResolvableType + * + * @return ResolvableType + */ @JvmStatic fun forClass(clazz: Class<*>?): ResolvableType { return ResolvableType(clazz) } + /** + * 基于给定的Field, 去为该类型解析成为ResolvableType + * + * @param field 要去进行解析的字段 + * @return 为该字段解析得到的ResolvableType + */ @JvmStatic fun forField(field: Field): ResolvableType { return forType(null, FieldTypeProvider(field), null) } + /** + * 指定Field以及该Field的实现类, 从而去解析成为ResolvableType, + * 有可能父类定义了一个T[]的字段, 具体的类型是子类给定的, 如果没有子类, 这个T[]的类型就无法被解析出来, + * 但是提供了子类之后, 我们可以基于子类, 去解析父类的泛型, 从而解析得到这个T + * + * @param field field, 可能为父类当中的字段 + * @param implementingClass 该字段对应的类的实现类 + * @return 针对该Field去进行描述得到的ResolvableType + */ + @JvmStatic + fun forField(field: Field, implementingClass: Class<*>?): ResolvableType { + val owner = forType(implementingClass).`as`(field.declaringClass) + return forType(null, FieldTypeProvider(field), owner.asVariableResolver()) + } + + /** + * 获取指定的Field的指定嵌套层级的Type信息 + * + * @param field Field, 待解析的字段 + * @param nestingLevel nestingLevel, 要获取的泛型的嵌套等级 + * @return 获取到的字段的指定层级的泛型的Type信息对应的ResolvableType + */ + @JvmStatic + fun forField(field: Field, nestingLevel: Int): ResolvableType { + return forField(field).getNested(nestingLevel) + } + + /** + * 指定Field以及该Field的实现类, 从而对该字段的指定层级的泛型信息, 去解析成为ResolvableType, + * 有可能父类定义了一个T[]的字段, 具体的类型是子类给定的, 如果没有子类, 这个T[]的类型就无法被解析出来, + * 但是提供了子类之后, 我们可以基于子类, 去解析父类的泛型, 从而解析得到这个T + * + * @param field field, 可能为父类当中的字段 + * @param nestingLevel nestingLevel, 要获取的泛型的嵌套等级 + * @param implementingClass 该字段对应的类的实现类 + * @return 针对该Field去进行描述得到的ResolvableType + */ + @JvmStatic + fun forField(field: Field, nestingLevel: Int, implementingClass: Class<*>?): ResolvableType { + return forField(field, implementingClass).getNested(nestingLevel) + } + + /** + * 针对给定的Type去解析成为ResolvableType + * + * @param type type + * @return 解析得到的ResolvableType + */ @JvmStatic fun forType(type: Type?): ResolvableType { return forType(type, null, null) } + /** + * 针对给定的Type去解析成为ResolvableType + * + * @param type type + * @param owner 该type对应的Owner, 比如字段对应的具体实现类 + * @return 解析得到的ResolvableType + */ @JvmStatic fun forType(type: Type?, owner: ResolvableType?): ResolvableType { return forType(type, owner?.asVariableResolver()) } + /** + * 针对给定的Type去解析成为ResolvableType + * + * @param type type + * @param variableResolver 提供对于TypeVariable的解析的解析器(很可能由owner提供, 让子类去解析父类的泛型信息) + * @return 解析得到的ResolvableType + */ @JvmStatic fun forType( type: Type?, @@ -484,6 +611,14 @@ open class ResolvableType { return forType(type, null, variableResolver) } + /** + * 针对给定的Type去解析成为ResolvableType + * + * @param type type + * @param typeProvider typeProvider(如果type为null, 支持从typeProvider当中去进行getType) + * @param variableResolver 提供对于TypeVariable的解析的解析器(很可能由owner提供, 让子类去解析父类的泛型信息) + * @return 解析得到的ResolvableType + */ @JvmStatic private fun forType( type: Type?, @@ -517,6 +652,19 @@ open class ResolvableType { return forMethodParameter(MethodParameter(method, index)) } + /** + * 将一个方法参数去转换成为[ResolvableType] + * + * @param method 方法 + * @param index 方法参数index? + * @param implementingClass 该方法的具体实现类 + * @return 解析得到描述该方法参数的ResolveType + */ + @JvmStatic + fun forMethodParameter(method: Method, index: Int, implementingClass: Class<*>): ResolvableType { + return forMethodParameter(MethodParameter(method, index, implementingClass)) + } + /** * 根据给定的方法的返回值去构建出来[ResolvableType] * @@ -536,9 +684,62 @@ open class ResolvableType { */ @JvmStatic fun forMethodParameter(methodParameter: MethodParameter): ResolvableType { - // 先构建出来一个type=ParameterizedType的ResolvableType去作为VariableResolver, 去提供泛型的解析 - val owner = forType(type = methodParameter.getGenericParameterType(), variableResolver = null) - return forType(methodParameter.getGenericParameterType(), owner.asVariableResolver()) + return forMethodParameter(methodParameter, targetType = null) + } + + /** + * 将一个方法参数去转换成为ResolvableType + * + * @param methodParameter 方法参数 + * @param targetType targetType + * @return 针对该方法参数去解析得到的ResolvableType + */ + @JvmStatic + fun forMethodParameter(methodParameter: MethodParameter, @Nullable targetType: Type?): ResolvableType { + return forMethodParameter(methodParameter, targetType, methodParameter.getNestingLevel()) + } + + /** + * 将一个方法参数去转换成为ResolvableType + * + * @param methodParameter 方法参数 + * @param implementationType 该方法参数对应的实现类的类型 + * @return 针对该方法参数, 去解析得到的ResolvableType + */ + @JvmStatic + fun forMethodParameter( + methodParameter: MethodParameter, + @Nullable implementationType: ResolvableType? + ): ResolvableType { + // 获取到具体的实现类(如果不存在的话, 那么从方法参数当中去进行获取containingClass) + val implementationTypeToUse = implementationType ?: forType(methodParameter.getContainingClass()) + // 将实现类使用as转换为方法所在的类... + val owner = implementationTypeToUse.`as`(methodParameter.getDeclaringClass()) + + return forType( + null, + MethodParameterTypeProvider(methodParameter), + owner.asVariableResolver() + ).getNested(methodParameter.getNestingLevel(), methodParameter.getOriginTypeIndexesPerLevel()) + } + + /** + * 将一个方法参数类型的指定泛型嵌套级别的参数, 去转换成为ResolvableType + * + * @param methodParameter 方法参数 + * @param nestingLevel 泛型参数嵌套级别 + * @param targetType targetType + * @return 方法参数/方法参数的泛型信息, 去转换得到的ResolvableType + */ + @JvmStatic + fun forMethodParameter(methodParameter: MethodParameter, targetType: Type?, nestingLevel: Int): ResolvableType { + // 使用containingClass去解析成为ResolvableType, 再使用as切换到declaringClass的ResolvableType + val owner = forType(methodParameter.getContainingClass()).`as`(methodParameter.getDeclaringClass()) + return forType( + targetType, + MethodParameterTypeProvider(methodParameter), + owner.asVariableResolver() + ).getNested(nestingLevel, methodParameter.getOriginTypeIndexesPerLevel()) } /** @@ -596,6 +797,16 @@ open class ResolvableType { } } + private class MethodParameterTypeProvider(private val methodParameter: MethodParameter) : TypeProvider { + override fun getType(): Type { + return methodParameter.getGenericParameterType() + } + + override fun getSource(): Any { + return this.methodParameter + } + } + /** * 提供对于TypeVariable的解析的Resolver策略接口 diff --git a/settings.gradle.kts b/settings.gradle.kts index 8c033b66..0bc9af6a 100755 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -62,6 +62,10 @@ include(":kotlin-debugger-project:kotlin-debugger-bistoury") include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-spy") include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-agent") include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-client") +include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-proxy") +include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-remoting") +include(":kotlin-debugger-project:kotlin-debugger-bistoury:kotlin-debugger-bistoury-serverside-common") + include(":kotlin-debugger-project:kotlin-debugger-arthas:kotlin-debugger-arthas-client") include(":kotlin-debugger-project:kotlin-debugger-arthas:kotlin-debugger-arthas-common") include(":kotlin-debugger-project:kotlin-debugger-arthas:kotlin-debugger-arthas-cli") \ No newline at end of file