@@ -16,6 +16,7 @@ import com.omegar.mvp.compiler.entities.View
1616import com.omegar.mvp.compiler.processors.OriginatingMarker
1717import com.omegar.mvp.compiler.processors.ViewParser
1818import com.omegar.mvp.viewstate.strategy.MoxyViewCommand
19+ import com.squareup.kotlinpoet.TypeName
1920import com.squareup.kotlinpoet.ksp.TypeParameterResolver
2021import com.squareup.kotlinpoet.ksp.toClassName
2122import com.squareup.kotlinpoet.ksp.toTypeName
@@ -53,27 +54,18 @@ class KspViewParser(
5354 presenterCache[presenterKey]?.let {
5455 return it
5556 }
56-
57- val (superPresenter, view) =
58- presenterDeclaration
59- .superTypes
60- .firstNotNullOf { reference ->
61- (reference.resolve().declaration as ? KSClassDeclaration )
62- ?.takeIf { it.classKind == ClassKind .CLASS }
63- ?.let {
64- it to reference.getView()!!
65- }
66- }
57+ val (superPresenter, view) = presenterDeclaration.getSuperPresenterAndView()
6758
6859 val viewClassName = view.toClassName()
6960 val viewKey = viewClassName.simpleName
7061
7162 val viewDeclaration = view.declaration as KSClassDeclaration
7263
64+ val superView = this (superPresenter)
7365 viewCache[viewKey]?.let {
7466 val newView = it.copy(
7567 presenterClassName = presenterDeclaration.toClassName(),
76- parent = this (superPresenter)
68+ parent = superView
7769 )
7870 .putTags(presenterDeclaration, viewDeclaration)
7971 presenterCache[presenterKey] = newView
@@ -96,13 +88,13 @@ class KspViewParser(
9688 View (
9789 className = viewClassName,
9890 presenterClassName = presenterDeclaration.toClassName(),
99- methods = viewDeclaration.getMethods(),
91+ methods = viewDeclaration.getMethods(superView ),
10092 viewTypeParams = viewDeclaration.typeParameters
10193 .filterNot { mvpView.isAssignableFrom(it.bounds.first().resolve()) }
10294 .map { it.toTypeVariableName() },
10395 presenterInnerTypeParams = view.innerArguments.map { it.toTypeName(presenterDeclaration.typeParameters.toTypeParameterResolver()) },
10496 reflectorPackage = reflectorPackage,
105- parent = this (superPresenter)
97+ parent = superView
10698 ).putTags(presenterDeclaration, viewDeclaration)
10799 }
108100
@@ -112,7 +104,18 @@ class KspViewParser(
112104 return newView
113105 }
114106
115- private fun KSTypeReference.getView (): KSType ? {
107+ private fun KSClassDeclaration.getSuperPresenterAndView (): Pair <KSClassDeclaration , KSType > {
108+ return superTypes
109+ .firstNotNullOf { reference ->
110+ (reference.resolve().declaration as ? KSClassDeclaration )
111+ ?.takeIf { it.classKind == ClassKind .CLASS }
112+ ?.let {
113+ it to reference.findView()!!
114+ }
115+ }
116+ }
117+
118+ private fun KSTypeReference.findView (): KSType ? {
116119 val type = element
117120 ?.typeArguments
118121 ?.asSequence()
@@ -139,24 +142,40 @@ class KspViewParser(
139142 }
140143 }
141144
142- private fun KSClassDeclaration.getMethods (): List <View .Method > {
143- val parameterResolver = typeParameters.toTypeParameterResolver()
144- return declarations.mapNotNull { declaration ->
145+ private fun KSClassDeclaration.getMethods (superView : View ? ): List <View .Method > {
146+ val parameterResolver: TypeParameterResolver = typeParameters.toTypeParameterResolver()
147+ val typeNameResolverMap = mutableMapOf<KSDeclaration ?, TypeNameResolver >()
148+ val additionalSequence = superTypes
149+ .map { it.resolve() }
150+ .filter { it.toClassName() != superView?.className }
151+ .map {
152+ typeNameResolverMap[it.declaration] = TypeNameResolver (it, parameterResolver)
153+ it.declaration
154+ }
155+ .filterIsInstance<KSClassDeclaration >()
156+ .flatMap {
157+ it.declarations
158+ }
159+ val typeNameResolver = TypeNameResolver (emptyList(), this , parameterResolver)
160+ return (declarations + additionalSequence)
161+ .mapNotNull { declaration ->
145162 when (declaration) {
146163 is KSFunctionDeclaration -> {
147164 if (declaration.simpleName.getShortName() in ANY_FUNCTION_SIMPLE_NAME ) null else {
148- declaration.toMethod(parameterResolver )
165+ declaration.toMethod(typeNameResolverMap[declaration.parentDeclaration] ? : typeNameResolver )
149166 }
150167 }
168+
151169 is KSPropertyDeclaration -> {
152- declaration.toMethod(parameterResolver )
170+ declaration.toMethod(typeNameResolverMap[declaration.parentDeclaration] ? : typeNameResolver )
153171 }
172+
154173 else -> null
155174 }
156175 }.toList()
157- }
176+ }
158177
159- private fun KSFunctionDeclaration.toMethod (resolver : TypeParameterResolver ): View .Method {
178+ private fun KSFunctionDeclaration.toMethod (resolver : TypeNameResolver ): View .Method {
160179 val params = parameters.map {
161180 View .Method .Param (
162181 name = it.name?.getShortName() ? : PROPERTY_PARAM_NAME ,
@@ -171,7 +190,7 @@ class KspViewParser(
171190 ).putTags(this )
172191 }
173192
174- private fun KSPropertyDeclaration.toMethod (resolver : TypeParameterResolver ): View .Method {
193+ private fun KSPropertyDeclaration.toMethod (resolver : TypeNameResolver ): View .Method {
175194 return View .Method (
176195 name = simpleName.getShortName(),
177196 type = View .Method .Type .Property (
@@ -213,4 +232,39 @@ class KspViewParser(
213232 putTag(KspOriginatingMarker .Files ::class , KspOriginatingMarker .Files (declarations.mapNotNull { it.containingFile }))
214233 }
215234
235+ private fun KSTypeReference.toTypeName (resolver : TypeNameResolver ): TypeName {
236+ val ksType = this .resolve()
237+ return when (val declaration = ksType.declaration) {
238+ is KSTypeParameter -> resolver[declaration.name.getShortName()].copy(nullable = ksType.isMarkedNullable)
239+ else -> toTypeName(resolver.parentTypeParameterResolver)
240+ }
241+ }
242+
243+ private class TypeNameResolver (
244+ innerArguments : List <KSTypeArgument >,
245+ declaration : KSDeclaration ,
246+ val parentTypeParameterResolver : TypeParameterResolver
247+ ) {
248+ private val innerParametersMap = mutableMapOf<String , TypeName >()
249+
250+ constructor (
251+ type: KSType ,
252+ parentTypeParameterResolver: TypeParameterResolver
253+ ) : this (type.innerArguments, type.declaration, parentTypeParameterResolver)
254+
255+ init {
256+ val innerTypeNames = innerArguments.map { it.toTypeName(parentTypeParameterResolver) }
257+ declaration.typeParameters.mapIndexed { index, ksTypeParameter ->
258+ val typeName = innerTypeNames.getOrNull(index) ? : return @mapIndexed
259+ innerParametersMap[ksTypeParameter.name.getShortName()] = typeName
260+ }
261+
262+ }
263+
264+ operator fun get (index : String ): TypeName {
265+ return innerParametersMap[index] ? : parentTypeParameterResolver[index]
266+ }
267+
268+ }
269+
216270}
0 commit comments