J2K: Fix type parameters in LHS of callable reference
This commit is contained in:
@@ -450,13 +450,20 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
return JKMethodReferenceExpression(
|
||||
qualifierExpression?.toJK() ?: JKStubExpression(),
|
||||
methodReferenceQualifier(),
|
||||
symbol,
|
||||
functionalType(),
|
||||
isConstructor
|
||||
)
|
||||
}
|
||||
|
||||
fun PsiMethodReferenceExpression.methodReferenceQualifier(): JKExpression {
|
||||
val qualifierType = qualifierType
|
||||
if (qualifierType != null) return JKTypeQualifierExpression(typeFactory.fromPsiType(qualifierType.type))
|
||||
|
||||
return qualifierExpression?.toJK() ?: JKStubExpression()
|
||||
}
|
||||
|
||||
fun PsiReferenceExpression.toJK(): JKExpression {
|
||||
if (this is PsiMethodReferenceExpression) return toJK()
|
||||
val target = resolve()
|
||||
@@ -476,6 +483,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
is JKFieldSymbol -> JKFieldAccessExpression(symbol)
|
||||
is JKPackageSymbol -> JKPackageAccessExpression(symbol)
|
||||
is JKMethodSymbol -> JKMethodAccessExpression(symbol)
|
||||
is JKTypeParameterSymbol -> JKTypeQualifierExpression(JKTypeParameterType(symbol))
|
||||
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||
}.qualified(qualifierExpression?.toJK()).also {
|
||||
it.withFormattingFrom(this)
|
||||
|
||||
+12
-6
@@ -32,19 +32,25 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
|
||||
.safeAs<JKClassType>()
|
||||
?.singleFunctionParameterTypes()
|
||||
|
||||
val receiverParameter = element.qualifier
|
||||
val qualifierExpression = element.qualifier
|
||||
.nullIfStubExpression()
|
||||
?.safeAs<JKClassAccessExpression>()
|
||||
?.takeIf { symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall }
|
||||
?.let { classAccessExpression ->
|
||||
|
||||
val receiverParameter = if (symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall) {
|
||||
val type = when (qualifierExpression) {
|
||||
is JKTypeQualifierExpression -> qualifierExpression.type
|
||||
is JKClassAccessExpression -> JKClassType(qualifierExpression.identifier)
|
||||
else -> null
|
||||
}
|
||||
if (type != null) {
|
||||
JKParameter(
|
||||
JKTypeElement(
|
||||
parametersTypesByFunctionalInterface?.firstOrNull() ?: JKClassType(classAccessExpression.identifier)
|
||||
parametersTypesByFunctionalInterface?.firstOrNull() ?: type
|
||||
),
|
||||
JKNameIdentifier(RECEIVER_NAME),
|
||||
isVarArgs = false
|
||||
)
|
||||
}
|
||||
} else null
|
||||
} else null
|
||||
|
||||
val explicitParameterTypesByFunctionalInterface =
|
||||
if (receiverParameter != null) parametersTypesByFunctionalInterface?.drop(1)
|
||||
|
||||
@@ -146,6 +146,10 @@ internal class JKCodeBuilder(context: NewJ2kConverterContext) {
|
||||
printer.renderSymbol(methodAccessExpression.identifier, methodAccessExpression)
|
||||
}
|
||||
|
||||
override fun visitTypeQualifierExpression(typeQualifierExpression: JKTypeQualifierExpression) {
|
||||
printer.renderType(typeQualifierExpression.type, typeQualifierExpression)
|
||||
}
|
||||
|
||||
override fun visitFileRaw(file: JKFile) {
|
||||
if (file.packageDeclaration.name.value.isNotEmpty()) {
|
||||
file.packageDeclaration.accept(this)
|
||||
|
||||
@@ -201,6 +201,11 @@ class JKMethodAccessExpression(val identifier: JKMethodSymbol) : JKExpression()
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitMethodAccessExpression(this)
|
||||
}
|
||||
|
||||
class JKTypeQualifierExpression(val type: JKType) : JKExpression() {
|
||||
override fun calculateType(typeFactory: JKTypeFactory): JKType? = null
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitTypeQualifierExpression(this)
|
||||
}
|
||||
|
||||
class JKMethodReferenceExpression(
|
||||
qualifier: JKExpression,
|
||||
val identifier: JKSymbol,
|
||||
|
||||
@@ -84,6 +84,7 @@ abstract class JKVisitor {
|
||||
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression)
|
||||
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
|
||||
open fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) = visitExpression(methodAccessExpression)
|
||||
open fun visitTypeQualifierExpression(typeQualifierExpression: JKTypeQualifierExpression) = visitExpression(typeQualifierExpression)
|
||||
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) =
|
||||
visitExpression(methodReferenceExpression)
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// RUNTIME_WITH_FULL_JDK
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TestLambda<T> {
|
||||
public static class Box<Q> {
|
||||
|
||||
private Q value;
|
||||
public Q unbox() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Box(Q q) {
|
||||
value = q;
|
||||
}
|
||||
}
|
||||
|
||||
public String toStringAllBox(List<Box<T>> list) {
|
||||
return list.stream().map(Box<T>::unbox).map(T::toString).reduce((s1,s2) -> s1 + ", " + s2 ).orElse("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class TestLambda<T> {
|
||||
class Box<Q>(private val value: Q) {
|
||||
fun unbox(): Q {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun toStringAllBox(list: List<Box<T>>): String {
|
||||
return list.stream().map { obj: Box<T> -> obj.unbox() }.map { obj: T -> obj.toString() }
|
||||
.reduce { s1: String, s2: String -> "$s1, $s2" }.orElse("")
|
||||
}
|
||||
}
|
||||
+5
@@ -2422,6 +2422,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
||||
runTest("nj2k/testData/newJ2k/function/functionInFinalClass.java");
|
||||
}
|
||||
|
||||
@TestMetadata("genericMemberFunctionRef.java")
|
||||
public void testGenericMemberFunctionRef() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/function/genericMemberFunctionRef.java");
|
||||
}
|
||||
|
||||
@TestMetadata("internal.java")
|
||||
public void testInternal() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/function/internal.java");
|
||||
|
||||
Reference in New Issue
Block a user