J2K: Fix type parameters in LHS of callable reference
This commit is contained in:
@@ -450,13 +450,20 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return JKMethodReferenceExpression(
|
return JKMethodReferenceExpression(
|
||||||
qualifierExpression?.toJK() ?: JKStubExpression(),
|
methodReferenceQualifier(),
|
||||||
symbol,
|
symbol,
|
||||||
functionalType(),
|
functionalType(),
|
||||||
isConstructor
|
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 {
|
fun PsiReferenceExpression.toJK(): JKExpression {
|
||||||
if (this is PsiMethodReferenceExpression) return toJK()
|
if (this is PsiMethodReferenceExpression) return toJK()
|
||||||
val target = resolve()
|
val target = resolve()
|
||||||
@@ -476,6 +483,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
is JKFieldSymbol -> JKFieldAccessExpression(symbol)
|
is JKFieldSymbol -> JKFieldAccessExpression(symbol)
|
||||||
is JKPackageSymbol -> JKPackageAccessExpression(symbol)
|
is JKPackageSymbol -> JKPackageAccessExpression(symbol)
|
||||||
is JKMethodSymbol -> JKMethodAccessExpression(symbol)
|
is JKMethodSymbol -> JKMethodAccessExpression(symbol)
|
||||||
|
is JKTypeParameterSymbol -> JKTypeQualifierExpression(JKTypeParameterType(symbol))
|
||||||
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||||
}.qualified(qualifierExpression?.toJK()).also {
|
}.qualified(qualifierExpression?.toJK()).also {
|
||||||
it.withFormattingFrom(this)
|
it.withFormattingFrom(this)
|
||||||
|
|||||||
+12
-6
@@ -32,19 +32,25 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
|
|||||||
.safeAs<JKClassType>()
|
.safeAs<JKClassType>()
|
||||||
?.singleFunctionParameterTypes()
|
?.singleFunctionParameterTypes()
|
||||||
|
|
||||||
val receiverParameter = element.qualifier
|
val qualifierExpression = element.qualifier
|
||||||
.nullIfStubExpression()
|
.nullIfStubExpression()
|
||||||
?.safeAs<JKClassAccessExpression>()
|
|
||||||
?.takeIf { symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall }
|
val receiverParameter = if (symbol.safeAs<JKMethodSymbol>()?.isStatic == false && !element.isConstructorCall) {
|
||||||
?.let { classAccessExpression ->
|
val type = when (qualifierExpression) {
|
||||||
|
is JKTypeQualifierExpression -> qualifierExpression.type
|
||||||
|
is JKClassAccessExpression -> JKClassType(qualifierExpression.identifier)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (type != null) {
|
||||||
JKParameter(
|
JKParameter(
|
||||||
JKTypeElement(
|
JKTypeElement(
|
||||||
parametersTypesByFunctionalInterface?.firstOrNull() ?: JKClassType(classAccessExpression.identifier)
|
parametersTypesByFunctionalInterface?.firstOrNull() ?: type
|
||||||
),
|
),
|
||||||
JKNameIdentifier(RECEIVER_NAME),
|
JKNameIdentifier(RECEIVER_NAME),
|
||||||
isVarArgs = false
|
isVarArgs = false
|
||||||
)
|
)
|
||||||
}
|
} else null
|
||||||
|
} else null
|
||||||
|
|
||||||
val explicitParameterTypesByFunctionalInterface =
|
val explicitParameterTypesByFunctionalInterface =
|
||||||
if (receiverParameter != null) parametersTypesByFunctionalInterface?.drop(1)
|
if (receiverParameter != null) parametersTypesByFunctionalInterface?.drop(1)
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ internal class JKCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
printer.renderSymbol(methodAccessExpression.identifier, methodAccessExpression)
|
printer.renderSymbol(methodAccessExpression.identifier, methodAccessExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitTypeQualifierExpression(typeQualifierExpression: JKTypeQualifierExpression) {
|
||||||
|
printer.renderType(typeQualifierExpression.type, typeQualifierExpression)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFileRaw(file: JKFile) {
|
override fun visitFileRaw(file: JKFile) {
|
||||||
if (file.packageDeclaration.name.value.isNotEmpty()) {
|
if (file.packageDeclaration.name.value.isNotEmpty()) {
|
||||||
file.packageDeclaration.accept(this)
|
file.packageDeclaration.accept(this)
|
||||||
|
|||||||
@@ -201,6 +201,11 @@ class JKMethodAccessExpression(val identifier: JKMethodSymbol) : JKExpression()
|
|||||||
override fun accept(visitor: JKVisitor) = visitor.visitMethodAccessExpression(this)
|
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(
|
class JKMethodReferenceExpression(
|
||||||
qualifier: JKExpression,
|
qualifier: JKExpression,
|
||||||
val identifier: JKSymbol,
|
val identifier: JKSymbol,
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ abstract class JKVisitor {
|
|||||||
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression)
|
open fun visitPackageAccessExpression(packageAccessExpression: JKPackageAccessExpression) = visitExpression(packageAccessExpression)
|
||||||
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
|
open fun visitClassAccessExpression(classAccessExpression: JKClassAccessExpression) = visitExpression(classAccessExpression)
|
||||||
open fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) = visitExpression(methodAccessExpression)
|
open fun visitMethodAccessExpression(methodAccessExpression: JKMethodAccessExpression) = visitExpression(methodAccessExpression)
|
||||||
|
open fun visitTypeQualifierExpression(typeQualifierExpression: JKTypeQualifierExpression) = visitExpression(typeQualifierExpression)
|
||||||
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) =
|
open fun visitMethodReferenceExpression(methodReferenceExpression: JKMethodReferenceExpression) =
|
||||||
visitExpression(methodReferenceExpression)
|
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");
|
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")
|
@TestMetadata("internal.java")
|
||||||
public void testInternal() throws Exception {
|
public void testInternal() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/function/internal.java");
|
runTest("nj2k/testData/newJ2k/function/internal.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user