Skip to content

Commit

Permalink
Fixed import type resolution and super type references. (#382)
Browse files Browse the repository at this point in the history
* Fixed import type resolution and super type references.

* Polish.
  • Loading branch information
traceyyoshima authored Nov 10, 2023
1 parent a5553aa commit bbea9f7
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 18 deletions.
38 changes: 31 additions & 7 deletions src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package org.openrewrite.kotlin

import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.classId
import org.jetbrains.kotlin.codegen.topLevelClassAsmType
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
Expand All @@ -33,6 +35,7 @@ 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.FirSuperReference
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
Expand Down Expand Up @@ -122,6 +125,10 @@ class KotlinTypeMapping(
Unknown.getInstance()
}

is FirSuperReference -> {
type(type.superTypeRef, signature)
}

is FirFile -> {
fileType(signature)
}
Expand All @@ -134,6 +141,10 @@ class KotlinTypeMapping(
methodInvocationType(type, signature)
}

is FirImport -> {
resolveImport(type, signature)
}

is FirJavaTypeRef -> {
type(type.type, parent, signature)
}
Expand Down Expand Up @@ -188,6 +199,13 @@ class KotlinTypeMapping(
}
}

@OptIn(SymbolInternals::class)
private fun resolveImport(type: FirImport, signature: String): JavaType? {
// If the symbol is not resolvable we return a NEW ShallowClass to prevent caching on a potentially resolvable class type.
val sym = type.importedFqName?.topLevelClassAsmType()?.classId?.toSymbol(firSession) ?: return ShallowClass.build(signature)
return type(sym.fir, signature)
}

private fun packageDirective(signature: String): JavaType? {
val jt = ShallowClass.build(signature)
typeCache.put(signature, jt)
Expand Down Expand Up @@ -290,15 +308,22 @@ class KotlinTypeMapping(
signature
)
}
val ref = type.toRegularClassSymbol(firSession)
var sym: Any? = type.toRegularClassSymbol(firSession)
if (type.typeArguments.isNotEmpty()) {
params = type.typeArguments.toList()
}
if (ref == null) {
typeCache.put(signature, Unknown.getInstance())
return Unknown.getInstance()

if (sym is FirRegularClassSymbol) {
sym.fir
} else {
sym = type.toSymbol(firSession)
if (sym is FirClassLikeSymbol<*>) {
sym.fir as FirClass
} else {
typeCache.put(signature, Unknown.getInstance())
return Unknown.getInstance()
}
}
ref.fir
}

else -> throw UnsupportedOperationException("Unexpected classType: ${type.javaClass}")
Expand Down Expand Up @@ -957,8 +982,7 @@ class KotlinTypeMapping(
clazz = if (type.classifier != null) {
TypeUtils.asFullyQualified(type(type.classifier!!))
} else {
val fq : JavaType = buildType(type.classifierQualifiedName)
fq as FullyQualified
createShallowClass(type.classifierQualifiedName)
}

if (type.typeArguments.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
Expand Down Expand Up @@ -88,6 +89,10 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
"{undefined}"
}

is FirAnonymousObject -> {
if (type.typeParameters.isNotEmpty()) anonymousParameterizedSignature(type) else anonymousClassSignature(type)
}

is FirClass -> {
if (type.typeParameters.isNotEmpty()) parameterizedSignature(type) else classSignature(type)
}
Expand Down Expand Up @@ -140,6 +145,10 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
signature(type.typeRef)
}

is FirSuperReference -> {
signature(type.superTypeRef)
}

is FirTypeParameter -> {
typeParameterSignature(type)
}
Expand Down Expand Up @@ -180,6 +189,23 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
}
}

private fun anonymousClassSignature(type: FirAnonymousObject): String {
val sig = StringBuilder(type.symbol.classId.asFqNameString())
for (supertype in type.superTypeRefs) {
sig.append(signature(supertype))
}
return sig.toString()
}

private fun anonymousParameterizedSignature(type: FirAnonymousObject): String {
val sig = StringBuilder(classSignature(type))
val joiner = StringJoiner(", ", "<", ">")
for (tp in type.typeParameters) {
joiner.add(signature(tp, type))
}
return sig.append(joiner).toString()
}

override fun arraySignature(type: Any): String {
throw UnsupportedOperationException("This should never happen.")
}
Expand All @@ -194,7 +220,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
is FirResolvedTypeRef -> classSignature(type.type)
is FirResolvedQualifier -> convertClassIdToFqn(type.classId)
else -> {
""
throw UnsupportedOperationException("Unsupported class type: ${type.javaClass.name}")
}
}
}
Expand Down Expand Up @@ -249,7 +275,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
is FirRegularClass -> parameterizedSignature(type)
is FirResolvedQualifier -> parameterizedSignature(type)
else -> {
""
throw UnsupportedOperationException("Unsupported parameterized FirClass type: ${type.javaClass.name}")
}
}
}
Expand Down Expand Up @@ -396,13 +422,15 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
@OptIn(SymbolInternals::class)
private fun resolvedNameReferenceSignature(type: FirResolvedNamedReference, parent: Any?): String {
return when (val sym = type.resolvedSymbol) {
is FirBackingFieldSymbol -> signature(sym.fir, parent)
is FirConstructorSymbol -> signature(sym.fir, parent)
is FirEnumEntrySymbol -> signature(sym.fir, parent)
is FirFieldSymbol -> signature(sym.fir, parent)
is FirNamedFunctionSymbol -> signature(sym.fir, parent)
is FirPropertySymbol -> signature(sym.fir, parent)
is FirValueParameterSymbol -> signature(sym.fir, parent)
else -> {
""
throw UnsupportedOperationException("Unsupported FirResolvedNamedReference type: ${type.javaClass.name}")
}
}
}
Expand Down Expand Up @@ -445,7 +473,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
}
}

else -> ""
else -> throw UnsupportedOperationException("Unsupported FirTypeProjection: ${type.javaClass.name}")
}
}

Expand Down Expand Up @@ -495,7 +523,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val
is BinaryJavaTypeParameter -> javaTypeParameterSignature(type)
is JavaWildcardType -> javaWildCardSignature(type)
is JavaValueParameter -> signature(type.type)
else -> ""
else -> throw UnsupportedOperationException("Unsupported JavaElement: ${type.javaClass.name}")
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,23 @@ fun test() {
);
}

@Issue("https://github.com/openrewrite/rewrite-kotlin/issues/373")
@Test
void javaTypeFullyQualified() {
rewriteRun(
kotlin(
"""
@file:Suppress("UNUSED_PARAMETER")
open class Object<T>
class Test(name: String, any: Any)
fun <T> foo(name: String) =
Test(name, object : Object<T>() {})
"""
)
);
}

@Test
void variableTypes() {
rewriteRun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ annotation class B
}

@Test
void AnnotationEntryTrailingComma() {
void annotationEntryTrailingComma() {
rewriteRun(
spec -> spec.parser(KotlinParser.builder().classpath("jackson-annotations")),
kotlin(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ void superAccess() {
rewriteRun(
kotlin(
"""
open class Super {
val id : String = ""
open class A {
val id : Int = 0
}
class Test : Super() {
fun getId ( ) : String {
class B : A ( ) {
fun getId ( ) : Int {
return super . id
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.openrewrite.kotlin.tree;

import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.ExpectedToFail;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.kotlin.Assertions.kotlin;
Expand All @@ -28,6 +27,7 @@ void variableTypeInParentheses() {
rewriteRun(
kotlin(
"""
@Suppress("UNUSED_PARAMETER")
class A {
internal fun <T> parseMappedType(
mappedType: (String),
Expand Down

0 comments on commit bbea9f7

Please sign in to comment.