J2K: convert method references according to special methods
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.tree.IElementType
|
||||
@@ -728,14 +729,42 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
|
||||
val callParams = if (needThis) parameters.drop(1) else parameters
|
||||
val statement = if (expression.isConstructor) {
|
||||
MethodCallExpression.build(null, convertMethodReferenceQualifier(qualifier), callParams.map { it.first }, emptyList(), false).assignNoPrototype()
|
||||
|
||||
val specialMethod = method?.let { SpecialMethod.match(it, callParams.size, converter.services) }
|
||||
val statement: Statement = if (expression.isConstructor) {
|
||||
MethodCallExpression.build(null, convertMethodReferenceQualifier(qualifier), callParams.map { it.first }, emptyList(), false)
|
||||
}
|
||||
else if (specialMethod != null) {
|
||||
val factory = PsiElementFactory.SERVICE.getInstance(converter.project)
|
||||
val fakeReceiver = receiver?.let {
|
||||
val psiExpression = if (qualifier is PsiExpression) qualifier else factory.createExpressionFromText("fakeReceiver", null)
|
||||
psiExpression.convertedExpression = it.first
|
||||
psiExpression
|
||||
}
|
||||
val fakeParams = callParams.mapIndexed {
|
||||
i, param ->
|
||||
with(factory.createExpressionFromText("fake$i", null)) {
|
||||
this.convertedExpression = param.first
|
||||
this
|
||||
}
|
||||
}
|
||||
val patchedConverter = codeConverter.withSpecialExpressionConverter(object : SpecialExpressionConverter {
|
||||
override fun convertExpression(expression: PsiExpression, codeConverter: CodeConverter): Expression? {
|
||||
val convertedExpression = expression.convertedExpression
|
||||
expression.convertedExpression = null
|
||||
return convertedExpression
|
||||
}
|
||||
})
|
||||
|
||||
specialMethod.convertCall(fakeReceiver, fakeParams.toTypedArray(), emptyList(), patchedConverter)!!
|
||||
}
|
||||
else {
|
||||
val referenceName = expression.referenceName!!
|
||||
MethodCallExpression.build(receiver?.first, referenceName, callParams.map { it.first }, emptyList(), false).assignNoPrototype()
|
||||
MethodCallExpression.build(receiver?.first, referenceName, callParams.map { it.first }, emptyList(), false)
|
||||
}
|
||||
|
||||
statement.assignNoPrototype()
|
||||
|
||||
val lambdaParameterList = ParameterList(
|
||||
if (parameters.size == 1 && !isKotlinFunctionType) {
|
||||
// for lambdas all parameters with types should be present
|
||||
@@ -766,6 +795,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private var PsiExpression.convertedExpression: Expression? by UserDataProperty(Key.create("CONVERTED_EXPRESSION"))
|
||||
|
||||
private fun isFunctionType(functionalType: PsiType?) = functionalType?.canonicalText?.startsWith("kotlin.jvm.functions.Function") ?: false
|
||||
|
||||
private fun convertMethodReferenceQualifier(qualifier: PsiElement): String {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// ERROR: Type inference failed: Not enough information to infer parameter T in fun <T : kotlin.Any!> emptyList(): kotlin.collections.(Mutable)List<T!>! Please specify it explicitly.
|
||||
// ERROR: Type inference failed: Not enough information to infer parameter T in fun <T> emptyList(): kotlin.collections.List<T> Please specify it explicitly.
|
||||
package test
|
||||
|
||||
import java.util.Collections
|
||||
@@ -72,7 +72,7 @@ internal class Java8Class {
|
||||
}
|
||||
|
||||
fun testLibraryFunctions() {
|
||||
val memberFunFromClass = { obj: String -> obj.length() }
|
||||
val memberFunFromClass = { obj: String -> obj.length }
|
||||
memberFunFromClass.invoke("str")
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ internal class Java8Class {
|
||||
}
|
||||
|
||||
fun testGenericFunctions() {
|
||||
val emptyList = { Collections.emptyList() }
|
||||
val emptyList = { emptyList() }
|
||||
emptyList.invoke()
|
||||
}
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ internal class Java8Class {
|
||||
}
|
||||
|
||||
fun testLibraryFunctions() {
|
||||
val memberFunFromClass = JFunction2<String, Int> { it.length() }
|
||||
val memberFunFromClass = JFunction2<String, Int> { it.length }
|
||||
memberFunFromClass.foo("str")
|
||||
|
||||
Thread(Runnable { System.out.println() }).start()
|
||||
Runnable { System.out.println() }.run()
|
||||
Thread(Runnable { println() }).start()
|
||||
Runnable { println() }.run()
|
||||
}
|
||||
|
||||
fun testOverloads() {
|
||||
@@ -137,10 +137,10 @@ internal class Java8Class {
|
||||
}
|
||||
|
||||
fun testGenericFunctions() {
|
||||
val emptyList = JFunction1<List<String>> { Collections.emptyList() }
|
||||
val emptyList = JFunction1<List<String>> { emptyList() }
|
||||
emptyList.foo()
|
||||
MethodReferenceHelperClass.staticFun1(JFunction1<List<String>> { Collections.emptyList() })
|
||||
h.memberFun1(JFunction1<List<String>> { Collections.emptyList() })
|
||||
MethodReferenceHelperClass.staticFun1(JFunction1<List<String>> { emptyList() })
|
||||
h.memberFun1(JFunction1<List<String>> { emptyList() })
|
||||
}
|
||||
|
||||
fun memberFun(): Int {
|
||||
|
||||
Reference in New Issue
Block a user