Skip to content

Commit cb670c6

Browse files
committed
Fix implementation methods for other interfaces (except first MvpView)
1 parent 582dcfc commit cb670c6

File tree

6 files changed

+93
-28
lines changed

6 files changed

+93
-28
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.omegar.mvp
2+
3+
interface Addon<N> {
4+
5+
var addon: N?
6+
get() = null
7+
set(value) {
8+
TODO()
9+
}
10+
11+
}

app/src/main/java/com/omegar/mvp/MoxyActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.omegar.mvp.ktx.providePresenter
66
import kotlin.time.Duration
77
import kotlin.time.Duration.Companion.seconds
88

9-
class MoxyActivity: MvpAppCompatActivity(R.layout.activity_moxy), MoxyView<Int> {
9+
class MoxyActivity: MvpAppCompatActivity(R.layout.activity_moxy), MoxyView {
1010

1111
companion object {
1212
var first: Boolean = true

app/src/main/java/com/omegar/mvp/MoxyFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import com.omegar.mvp.ktx.providePresenter
66
import kotlin.time.Duration
77
import kotlin.time.Duration.Companion.seconds
88

9-
class MoxyFragment : MvpAppCompatFragment(R.layout.activity_moxy), MoxyView<Int> {
9+
class MoxyFragment : MvpAppCompatFragment(R.layout.activity_moxy), MoxyView {
1010

1111
private val presenter: MoxyPresenter by providePresenter {
1212
MoxyPresenter()

app/src/main/java/com/omegar/mvp/MoxyPresenter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import kotlin.time.Duration
44

55

66
@InjectViewState
7-
class MoxyPresenter : BasePresenter<Long, MoxyView<Int>>() {
7+
class MoxyPresenter : BasePresenter<Long, MoxyView>() {
88

99
init {
1010
viewState.showToast("Hello World!")

app/src/main/java/com/omegar/mvp/MoxyView.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import com.omegar.mvp.viewstate.strategy.MoxyViewCommand
44
import com.omegar.mvp.viewstate.strategy.StrategyType.ONE_EXECUTION
55
import kotlin.time.Duration
66

7-
interface MoxyView<T>: BaseView {
7+
interface MoxyView: Addon<Long>, BaseView {
88

99

1010
var duration: Duration
1111

1212
@MoxyViewCommand(ONE_EXECUTION)
13-
fun test(count: T)
13+
fun test(count: Int)
1414

1515
@MoxyViewCommand(ONE_EXECUTION)
1616
fun showToast(message: String)

moxy/compiler/src/main/java/com/omegar/mvp/compiler/ksp/KspViewParser.kt

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.omegar.mvp.compiler.entities.View
1616
import com.omegar.mvp.compiler.processors.OriginatingMarker
1717
import com.omegar.mvp.compiler.processors.ViewParser
1818
import com.omegar.mvp.viewstate.strategy.MoxyViewCommand
19+
import com.squareup.kotlinpoet.TypeName
1920
import com.squareup.kotlinpoet.ksp.TypeParameterResolver
2021
import com.squareup.kotlinpoet.ksp.toClassName
2122
import 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

Comments
 (0)