Skip to content

Commit

Permalink
Fixed declaring types of function calls with generic type parameters. (
Browse files Browse the repository at this point in the history
…#337)

Fixed method signature for function calls with generic type parameters.
Added type to name of destructs based on return type from initializer.
Added method type from delegate constructor of anonymous objects.
  • Loading branch information
traceyyoshima authored Oct 9, 2023
1 parent 4ab685e commit abc7ddc
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,9 @@ class KotlinTypeMapping(typeCache: JavaTypeCache, firSession: FirSession) : Java
if ((functionCall.calleeReference as FirResolvedNamedReference).resolvedSymbol is FirNamedFunctionSymbol) {
val resolvedSymbol =
(functionCall.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirNamedFunctionSymbol
if (resolvedSymbol.containingClassLookupTag() != null) {
if (resolvedSymbol.dispatchReceiverType is ConeClassLikeType) {
resolvedDeclaringType = TypeUtils.asFullyQualified(type(resolvedSymbol.dispatchReceiverType))
} else if (resolvedSymbol.containingClassLookupTag() != null) {
val lookupTag: ConeClassLikeLookupTag = resolvedSymbol.containingClassLookupTag()!!
val classSymbol: FirRegularClassSymbol? = lookupTag.toFirRegularClassSymbol(firSession)
if (classSymbol != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession) : JavaTypeS
var owner = "{undefined}"
if (functionCall.explicitReceiver != null) {
owner = signature(functionCall.explicitReceiver!!.typeRef)
} else if ((functionCall.calleeReference as FirResolvedNamedReference).resolvedSymbol is FirConstructorSymbol) {
return signature((functionCall.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirConstructorSymbol)
} else if (functionCall.calleeReference is FirResolvedNamedReference) {
if ((functionCall.calleeReference as FirResolvedNamedReference).resolvedSymbol is FirNamedFunctionSymbol) {
val resolvedSymbol =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ class KotlinParserVisitor(
val args: JContainer<Expression>
saveCursor = cursor
val before = whitespace()
var constructorType: JavaType.Method? = null
args = if (source[cursor] == '(') {
if (anonymousObject.declarations.isNotEmpty() &&
anonymousObject.declarations[0] is FirPrimaryConstructor &&
Expand All @@ -586,6 +587,10 @@ class KotlinParserVisitor(
cursor(saveCursor)
val delegatedConstructor =
(anonymousObject.declarations[0] as FirPrimaryConstructor).delegatedConstructor!!
val type = typeMapping.type((delegatedConstructor.calleeReference as FirResolvedNamedReference).resolvedSymbol)
if (type is JavaType.Method) {
constructorType = type
}
mapFunctionalCallArguments(delegatedConstructor)
} else {
skip("(")
Expand Down Expand Up @@ -641,7 +646,7 @@ class KotlinParserVisitor(
clazz,
args,
body,
null
constructorType
)
}

Expand Down Expand Up @@ -1385,7 +1390,7 @@ class KotlinParserVisitor(
Markers.EMPTY,
emptyList(),
initializer.name.asString(),
null,
typeMapping.type((propertiesPairs[0].second as FirProperty).returnTypeRef),
null
),
emptyList(),
Expand Down Expand Up @@ -3776,7 +3781,7 @@ class KotlinParserVisitor(
Markers.EMPTY,
emptyList(),
componentCall.calleeReference.name.asString(),
null,
type,
null
)
} else {
Expand Down
62 changes: 62 additions & 0 deletions src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,5 +364,67 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Atomi
)
);
}

@Test
void destructs() {
rewriteRun(
kotlin(
"""
fun foo() {
val ( a , b , c ) = Triple ( 1 , 2 , 3 )
}
""", spec -> spec.afterRecipe(cu -> {
AtomicBoolean found = new AtomicBoolean(false);
new KotlinIsoVisitor<AtomicBoolean>() {
@Override
public K.DestructuringDeclaration visitDestructuringDeclaration(K.DestructuringDeclaration destructuringDeclaration, AtomicBoolean atomicBoolean) {
atomicBoolean.set(true);
return super.visitDestructuringDeclaration(destructuringDeclaration, atomicBoolean);
}

@Override
public J.NewClass visitNewClass(J.NewClass newClass, AtomicBoolean atomicBoolean) {
if ("Triple".equals(((J.Identifier) newClass.getClazz()).getSimpleName())) {
assertThat(newClass.getClazz().getType().toString()).isEqualTo("kotlin.Triple<Generic{A}, Generic{B}, Generic{C}>");
assertThat(newClass.getConstructorType().toString()).isEqualTo("kotlin.Triple{name=<constructor>,return=kotlin.Triple,parameters=[Generic{A},Generic{B},Generic{C}]}");
}
return super.visitNewClass(newClass, atomicBoolean);
}

@Override
public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable variable, AtomicBoolean atomicBoolean) {
switch (variable.getSimpleName()) {
case "<destruct>" -> assertThat(variable.getName().getType().toString())
.isEqualTo("kotlin.Triple<kotlin.Int, kotlin.Int, kotlin.Int>");
case "a" -> {
assertThat(variable.getVariableType().toString())
.isEqualTo("openRewriteFile0Kt{name=a,type=kotlin.Int}");
assertThat(variable.getInitializer()).isInstanceOf(J.MethodInvocation.class);
assertThat(((J.MethodInvocation) variable.getInitializer()).getMethodType().toString())
.isEqualTo("kotlin.Triple<kotlin.Int, kotlin.Int, kotlin.Int>{name=component1,return=kotlin.Int,parameters=[]}");
}
case "b" -> {
assertThat(variable.getVariableType().toString())
.isEqualTo("openRewriteFile0Kt{name=b,type=kotlin.Int}");
assertThat(variable.getInitializer()).isInstanceOf(J.MethodInvocation.class);
assertThat(((J.MethodInvocation) variable.getInitializer()).getMethodType().toString())
.isEqualTo("kotlin.Triple<kotlin.Int, kotlin.Int, kotlin.Int>{name=component2,return=kotlin.Int,parameters=[]}");
}
case "c" -> {
assertThat(variable.getVariableType().toString())
.isEqualTo("openRewriteFile0Kt{name=c,type=kotlin.Int}");
assertThat(variable.getInitializer()).isInstanceOf(J.MethodInvocation.class);
assertThat(((J.MethodInvocation) variable.getInitializer()).getMethodType().toString())
.isEqualTo("kotlin.Triple<kotlin.Int, kotlin.Int, kotlin.Int>{name=component3,return=kotlin.Int,parameters=[]}");
}
}
return super.visitVariable(variable, atomicBoolean);
}
}.visit(cu, found);
assertThat(found.get()).isTrue();
})
)
);
}
}
}

0 comments on commit abc7ddc

Please sign in to comment.