Skip to content

Commit

Permalink
Updated function call type and signature when value parameters are no…
Browse files Browse the repository at this point in the history
…t generic types. (#363)
  • Loading branch information
traceyyoshima authored Nov 7, 2023
1 parent a91eb3b commit 7cd560c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
14 changes: 10 additions & 4 deletions src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.dfa.DfaInternals
import org.jetbrains.kotlin.fir.resolve.dfa.symbol
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
Expand Down Expand Up @@ -611,7 +614,7 @@ class KotlinTypeMapping(
return methodInvocationType(fir, signature)
}

@OptIn(SymbolInternals::class)
@OptIn(SymbolInternals::class, DfaInternals::class)
fun methodInvocationType(function: FirFunctionCall, signature: String): JavaType.Method? {
val sym = function.calleeReference.toResolvedBaseSymbol() ?: return null
val receiver = if (sym is FirFunctionSymbol<*>) sym.receiverParameter else null
Expand Down Expand Up @@ -703,9 +706,12 @@ class KotlinTypeMapping(
if (function.toResolvedCallableSymbol()?.receiverParameter != null) {
paramTypes!!.add(type(function.toResolvedCallableSymbol()?.receiverParameter!!.typeRef))
}
for (param: FirExpression? in function.arguments) {
if (param != null) {
paramTypes!!.add(type(param.typeRef))
for ((index, p) in (function.toResolvedCallableSymbol()?.fir as FirFunction).valueParameters.withIndex()) {
val t = type(p.returnTypeRef)
if (t !is GenericTypeVariable) {
paramTypes!!.add(t)
} else {
paramTypes!!.add(type((function.arguments[index]).typeRef))
}
}
method.unsafeSet(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
Expand Down Expand Up @@ -366,13 +367,19 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
return sig.toString()
}

@OptIn(SymbolInternals::class)
private fun methodCallArgumentSignature(function: FirFunctionCall): String {
val genericArgumentTypes = StringJoiner(",", "[", "]")
if (function.toResolvedCallableSymbol()?.receiverParameter != null) {
genericArgumentTypes.add(signature(function.toResolvedCallableSymbol()?.receiverParameter!!.typeRef))
}
for (p in function.arguments) {
genericArgumentTypes.add(signature(p.typeRef, function))
for ((index, p) in (function.toResolvedCallableSymbol()?.fir as FirFunction).valueParameters.withIndex()) {
val sig = signature(p.returnTypeRef, function)
if (sig.startsWith("Generic{")) {
genericArgumentTypes.add(signature((function.arguments[index]).typeRef, function))
} else {
genericArgumentTypes.add(sig)
}
}
return genericArgumentTypes.toString()
}
Expand Down
33 changes: 30 additions & 3 deletions src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ void coneTypeProjection() {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicBoolean found) {
if (methodMatcher.matches(method)) {
assertThat(method.getMethodType().toString()).isEqualTo("kotlin.collections.MutableList<Generic{E}>{name=addAll,return=kotlin.Boolean,parameters=[kotlin.collections.List<kotlin.String>]}");
assertThat(method.getMethodType().toString()).isEqualTo("kotlin.collections.MutableList<Generic{E}>{name=addAll,return=kotlin.Boolean,parameters=[kotlin.collections.Collection<Generic{E}>]}");
found.set(true);
}
return super.visitMethodInvocation(method, found);
Expand Down Expand Up @@ -436,7 +436,7 @@ void genericIntersectionType() {
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicBoolean found) {
if (methodMatcher.matches(method)) {
assertThat(method.getMethodType().toString())
.isEqualTo("kotlin.collections.CollectionsKt{name=listOf,return=kotlin.collections.List<kotlin.Pair<kotlin.String, Generic{kotlin.Comparable<Generic{?}> & java.io.Serializable}>>,parameters=[kotlin.Array<Generic{? extends kotlin.Pair<kotlin.String, Generic{kotlin.Comparable<Generic{?}> & java.io.Serializable}>}>]}");
.isEqualTo("kotlin.collections.CollectionsKt{name=listOf,return=kotlin.collections.List<kotlin.Pair<kotlin.String, Generic{kotlin.Comparable<Generic{?}> & java.io.Serializable}>>,parameters=[kotlin.Array<Generic{? extends Generic{T}}>]}");
found.set(true);
}
return super.visitMethodInvocation(method, found);
Expand All @@ -462,7 +462,7 @@ void implicitInvoke() {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicBoolean atomicBoolean) {
if (matcher.matches(method)) {
assertThat(method.getMethodType().toString()).isEqualTo("kotlin.Function1<kotlin.collections.Collection<kotlin.Any>, kotlin.Unit>{name=invoke,return=kotlin.Unit,parameters=[kotlin.collections.List<kotlin.String>]}");
assertThat(method.getMethodType().toString()).isEqualTo("kotlin.Function1<kotlin.collections.Collection<kotlin.Any>, kotlin.Unit>{name=invoke,return=kotlin.Unit,parameters=[kotlin.collections.Collection<kotlin.Any>]}");
found.set(true);
}
return super.visitMethodInvocation(method, atomicBoolean);
Expand Down Expand Up @@ -502,6 +502,33 @@ public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess, AtomicBoolean f
);
}

@Test
void println() {
//noinspection RemoveRedundantQualifierName
rewriteRun(
kotlin(
"""
fun method() {
println("foo")
}
""", spec -> spec.afterRecipe(cu -> {
AtomicBoolean found = new AtomicBoolean(false);
new KotlinIsoVisitor<AtomicBoolean>() {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, AtomicBoolean atomicBoolean) {
if ("println".equals(method.getSimpleName())) {
assertThat(method.getMethodType().toString()).isEqualTo("kotlin.io.ConsoleKt{name=println,return=kotlin.Unit,parameters=[kotlin.Any]}");
found.set(true);
}
return super.visitMethodInvocation(method, atomicBoolean);
}
}.visit(cu, found);
assertThat(found.get()).isTrue();
})
)
);
}

@SuppressWarnings({"KotlinConstantConditions", "UnusedUnaryOperator", "RedundantExplicitType"})
@Test
void whenExpression() {
Expand Down

0 comments on commit 7cd560c

Please sign in to comment.