diff --git a/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index b22132eb7..4dc7023ef 100644 --- a/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -189,6 +190,14 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession) : JavaTypeS is FirOuterClassTypeParameterRef -> { return signature(type.symbol) } + + is ConeTypeVariable -> { + when (type) { + is ConeTypeParameterBasedTypeVariable -> { + return signature(type.typeParameterSymbol) + } + } + } } return "{undefined}" } @@ -387,6 +396,11 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession) : JavaTypeS s.append("}") } else if (type is ConeCapturedType && type.lowerType == null) { s.append("*") + } else if (type is ConeStubTypeForChainInference) { + if (type.typeArguments.isNotEmpty()) { + throw UnsupportedOperationException("Unsupported ConeTypeProjection contains type arguments" + type.javaClass.getName()) + } + s.append(signature(type.constructor.variable)) } else { throw IllegalArgumentException("Unsupported ConeTypeProjection " + type.javaClass.getName()) } diff --git a/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java b/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java index 4896e8da7..fe032c51f 100644 --- a/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java +++ b/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java @@ -17,10 +17,10 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.junitpioneer.jupiter.ExpectedToFail; import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.Issue; import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Flag; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; @@ -29,6 +29,7 @@ import org.openrewrite.test.RewriteTest; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; @@ -306,18 +307,28 @@ void javaLangObject() { class ParsingTest implements RewriteTest { @Test @Issue("https://github.com/openrewrite/rewrite-kotlin/issues/303") - @ExpectedToFail void coneTypeProjection() { rewriteRun( kotlin( """ - val labels: List = listOf("") - val label: String = "" - val newLabels = buildList { - addAll(labels) - add(label) + val newList = buildList { + addAll(listOf("")) } - """ + """, spec -> spec.afterRecipe(cu -> { + MethodMatcher methodMatcher = new MethodMatcher("kotlin.collections.MutableList addAll(..)"); + AtomicBoolean found = new AtomicBoolean(false); + new KotlinIsoVisitor() { + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicBoolean found) { + if (methodMatcher.matches(method)) { + assertThat(method.getMethodType().toString()).isEqualTo("kotlin.collections.MutableList{name=addAll,return=kotlin.Boolean,parameters=[kotlin.collections.Collection]}"); + found.set(true); + } + return super.visitMethodInvocation(method, found); + } + }.visit(cu, found); + assertThat(found.get()).isTrue(); + }) ) ); }