J2K: Support for method references
#KT-8721 Fixed
This commit is contained in:
@@ -582,6 +582,121 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitMethodReferenceExpression(expression: PsiMethodReferenceExpression) {
|
||||
val qualifierType = PsiMethodReferenceUtil.getQualifierType(expression)
|
||||
if (qualifierType is PsiArrayType) {
|
||||
result = DummyStringExpression(expression.text + " /* Currently unsupported in Kotlin */ ")
|
||||
return
|
||||
}
|
||||
|
||||
val qualifier = expression.qualifier
|
||||
if (qualifier == null) {
|
||||
// Reference should be qualified
|
||||
result = DummyStringExpression(expression.text)
|
||||
return
|
||||
}
|
||||
|
||||
// todo: For inner classes receiver can be omitted
|
||||
val contextClass = expression.getParentOfType<PsiClass>(false)
|
||||
val functionalType = expression.functionalInterfaceType
|
||||
|
||||
val isTypeInQualifier = (qualifier as? PsiReference)?.resolve() is PsiClass
|
||||
val isKotlinFunctionType = functionalType?.canonicalText?.startsWith("kotlin.jvm.functions.Function") ?: false
|
||||
|
||||
// method can be null in case of default constructor
|
||||
val method = expression.resolve() as? PsiMethod
|
||||
|
||||
val hasStaticModifier = method?.hasModifierProperty(PsiModifier.STATIC) ?: false
|
||||
val needThis = !hasStaticModifier && !expression.isConstructor && isTypeInQualifier
|
||||
|
||||
val parameters = method?.getParametersForMethodReference(needThis, isKotlinFunctionType) ?: emptyList()
|
||||
|
||||
val receiver = when {
|
||||
expression.isConstructor -> null
|
||||
needThis -> parameters.firstOrNull()
|
||||
isTypeInQualifier && method?.containingClass == contextClass -> null
|
||||
qualifier is PsiExpression -> codeConverter.convertExpression(qualifier) to null
|
||||
else -> null
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
else {
|
||||
val referenceName = expression.referenceName!!
|
||||
MethodCallExpression.build(receiver?.first, referenceName, callParams.map { it.first }, emptyList(), false).assignNoPrototype()
|
||||
}
|
||||
|
||||
val lambdaParameterList = ParameterList(
|
||||
if (parameters.size() == 1 && !isKotlinFunctionType) {
|
||||
// for lambdas all parameters with types should be present
|
||||
emptyList()
|
||||
} else {
|
||||
parameters.map { LambdaParameter(it.first, it.second).assignNoPrototype() }
|
||||
}).assignNoPrototype()
|
||||
|
||||
val lambdaExpression = LambdaExpression(
|
||||
lambdaParameterList,
|
||||
Block(listOf(statement),
|
||||
LBrace().assignNoPrototype(),
|
||||
RBrace().assignNoPrototype()).assignNoPrototype()
|
||||
).assignNoPrototype()
|
||||
|
||||
if (isKotlinFunctionType) {
|
||||
result = lambdaExpression
|
||||
}
|
||||
else {
|
||||
val convertedFunctionalType = converter.typeConverter.convertType(functionalType)
|
||||
result = MethodCallExpression.build(
|
||||
null,
|
||||
convertedFunctionalType.canonicalCode(),
|
||||
listOf(lambdaExpression),
|
||||
emptyList(),
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertMethodReferenceQualifier(qualifier: PsiElement): String {
|
||||
return when(qualifier) {
|
||||
is PsiExpression -> codeConverter.convertExpression(qualifier).canonicalCode()
|
||||
is PsiTypeElement -> converter.convertTypeElement(qualifier).type.canonicalCode()
|
||||
else -> qualifier.text
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiMethod.getParametersForMethodReference(needThis: Boolean, isKotlinFunctionType: Boolean): List<Pair<Identifier, Type?>> {
|
||||
val newParameters = arrayListOf<Pair<Identifier, Type?>>()
|
||||
|
||||
var thisClassType: ClassType? = null
|
||||
val thisClass = containingClass
|
||||
if (thisClass != null && isKotlinFunctionType) {
|
||||
val containingClassName = thisClass.qualifiedName ?: containingClass!!.name
|
||||
if (containingClassName != null) {
|
||||
val fqName = FqName(containingClassName)
|
||||
val identifier = Identifier(fqName.shortName().identifier, imports = listOf(fqName)).assignNoPrototype()
|
||||
thisClassType = ClassType(
|
||||
ReferenceElement(identifier, converter.convertTypeParameterList(thisClass.typeParameterList).parameters).assignNoPrototype(),
|
||||
Nullability.NotNull,
|
||||
converter.settings).assignNoPrototype()
|
||||
}
|
||||
}
|
||||
if (needThis) newParameters.add(Identifier("obj", false).assignNoPrototype() to thisClassType)
|
||||
|
||||
parameterList.parameters.forEach {
|
||||
val parameterType = if (isKotlinFunctionType) converter.typeConverter.convertType(it.type, Nullability.NotNull) else null
|
||||
newParameters.add(Identifier(it.name ?: "p", false).assignNoPrototype() to parameterType)
|
||||
}
|
||||
|
||||
if (newParameters.size() == 1 && !isKotlinFunctionType) {
|
||||
newParameters.clear()
|
||||
newParameters.add(Identifier("it", false).assignNoPrototype() to null)
|
||||
}
|
||||
|
||||
return newParameters
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: PsiExpression) {
|
||||
result = DummyStringExpression(expression.text)
|
||||
}
|
||||
|
||||
Vendored
+26
@@ -64,4 +64,30 @@ public class WithVarargConstructor {
|
||||
|
||||
public class T {
|
||||
public Set<String> set;
|
||||
}
|
||||
|
||||
public interface JFunction0 {
|
||||
void foo();
|
||||
}
|
||||
|
||||
public interface JFunction1ReturnType<T> {
|
||||
void foo(T t);
|
||||
}
|
||||
|
||||
public interface JFunction1<T> {
|
||||
T foo();
|
||||
}
|
||||
|
||||
public interface JFunction2<T, K> {
|
||||
K foo(T p);
|
||||
}
|
||||
|
||||
public class MethodReferenceHelperClass {
|
||||
public static void staticFun0(JFunction0 f) {}
|
||||
public static <T> void staticFun1(JFunction1<T> f) {}
|
||||
public static <T, K> void staticFun2(JFunction2<T, K> f) {}
|
||||
|
||||
public void memberFun0(JFunction0 f) {}
|
||||
public <T> void memberFun1(JFunction1<T> f) {}
|
||||
public <T, K> void memberFun2(JFunction2<T, K> f) {}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package test;
|
||||
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
public static Java8Class field = new Java8Class();
|
||||
public static Java8Class staticFun() {
|
||||
return new Java8Class();
|
||||
}
|
||||
public int memberFun() {return 1;}
|
||||
|
||||
public static String testOverloads() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
public static String testOverloads(int i) {
|
||||
return "2";
|
||||
}
|
||||
}
|
||||
|
||||
class Java8Class {
|
||||
private Java8Class field = new Java8Class();
|
||||
|
||||
public void testStaticFunction() {
|
||||
Function0 staticFunFromSameClass = Java8Class::staticFun;
|
||||
staticFunFromSameClass.invoke();
|
||||
|
||||
Function0 staticFunFromAnotherClass = Test::staticFun;
|
||||
staticFunFromAnotherClass.invoke();
|
||||
}
|
||||
|
||||
public void testMemberFunctionThroughClass() {
|
||||
Function1<Java8Class, Integer> memberFunFromClass = Java8Class::memberFun;
|
||||
memberFunFromClass.invoke(new Java8Class());
|
||||
}
|
||||
|
||||
public void testMemberFunctionThroughObject() {
|
||||
Java8Class obj = new Java8Class();
|
||||
Function0 memberFunFromSameClass = obj::memberFun;
|
||||
memberFunFromSameClass.invoke();
|
||||
|
||||
Test anotherObj = new Test();
|
||||
Function0 memFunFromAnotherClass = anotherObj::memberFun;
|
||||
memFunFromAnotherClass.invoke();
|
||||
|
||||
Function0 memberFunThroughObj1 = field::memberFun;
|
||||
memberFunThroughObj1.invoke();
|
||||
Function0 memberFunThroughObj2 = Test.field::memberFun;
|
||||
memberFunThroughObj2.invoke();
|
||||
Function0 memberFunThroughObj3 = Test.staticFun()::memberFun;
|
||||
memberFunThroughObj3.invoke();
|
||||
}
|
||||
|
||||
public void testConstructor() {
|
||||
Function0 constructorSameClass = Java8Class::new;
|
||||
constructorSameClass.invoke();
|
||||
|
||||
Function0 qualifiedConstructorSameClass = test.Java8Class::new;
|
||||
qualifiedConstructorSameClass.invoke();
|
||||
|
||||
Function0 constructorAnotherClass = Test::new;
|
||||
constructorAnotherClass.invoke();
|
||||
|
||||
Function0 qualifiedConstructorAnotherClass = test.Test::new;
|
||||
qualifiedConstructorAnotherClass.invoke();
|
||||
}
|
||||
|
||||
public void testLibraryFunctions() {
|
||||
Function1<String, Integer> memberFunFromClass = String::length;
|
||||
memberFunFromClass.invoke("str");
|
||||
}
|
||||
|
||||
public void testOverloads() {
|
||||
Function0<String> constructorWithoutParams = Test::testOverloads;
|
||||
constructorWithoutParams.invoke();
|
||||
|
||||
Function1<Integer, String> constructorWithParam = Test::testOverloads;
|
||||
constructorWithParam.invoke(2);
|
||||
}
|
||||
|
||||
public void testGenericFunctions() {
|
||||
Function0<List<String>> emptyList = Collections::emptyList;
|
||||
emptyList.invoke();
|
||||
}
|
||||
|
||||
public static int staticFun() { return 1; }
|
||||
|
||||
public int memberFun() { return 1; }
|
||||
|
||||
public Java8Class() {}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// ERROR: Type inference failed: Not enough information to infer parameter T in fun <T : kotlin.Any!> emptyList(): kotlin.(Mutable)List<T!>! Please specify it explicitly.
|
||||
package test
|
||||
|
||||
import java.util.Collections
|
||||
|
||||
class Test {
|
||||
public fun memberFun(): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
companion object {
|
||||
public var field: Java8Class = Java8Class()
|
||||
public fun staticFun(): Java8Class {
|
||||
return Java8Class()
|
||||
}
|
||||
|
||||
public fun testOverloads(): String {
|
||||
return "1"
|
||||
}
|
||||
|
||||
public fun testOverloads(i: Int): String {
|
||||
return "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Java8Class {
|
||||
private val field = Java8Class()
|
||||
|
||||
public fun testStaticFunction() {
|
||||
val staticFunFromSameClass = { staticFun() }
|
||||
staticFunFromSameClass.invoke()
|
||||
|
||||
val staticFunFromAnotherClass = { Test.staticFun() }
|
||||
staticFunFromAnotherClass.invoke()
|
||||
}
|
||||
|
||||
public fun testMemberFunctionThroughClass() {
|
||||
val memberFunFromClass = { obj: Java8Class -> obj.memberFun() }
|
||||
memberFunFromClass.invoke(Java8Class())
|
||||
}
|
||||
|
||||
public fun testMemberFunctionThroughObject() {
|
||||
val obj = Java8Class()
|
||||
val memberFunFromSameClass = { obj.memberFun() }
|
||||
memberFunFromSameClass.invoke()
|
||||
|
||||
val anotherObj = Test()
|
||||
val memFunFromAnotherClass = { anotherObj.memberFun() }
|
||||
memFunFromAnotherClass.invoke()
|
||||
|
||||
val memberFunThroughObj1 = { field.memberFun() }
|
||||
memberFunThroughObj1.invoke()
|
||||
val memberFunThroughObj2 = { Test.field.memberFun() }
|
||||
memberFunThroughObj2.invoke()
|
||||
val memberFunThroughObj3 = { Test.staticFun().memberFun() }
|
||||
memberFunThroughObj3.invoke()
|
||||
}
|
||||
|
||||
public fun testConstructor() {
|
||||
val constructorSameClass = { Java8Class() }
|
||||
constructorSameClass.invoke()
|
||||
|
||||
val qualifiedConstructorSameClass = { test.Java8Class() }
|
||||
qualifiedConstructorSameClass.invoke()
|
||||
|
||||
val constructorAnotherClass = { Test() }
|
||||
constructorAnotherClass.invoke()
|
||||
|
||||
val qualifiedConstructorAnotherClass = { test.Test() }
|
||||
qualifiedConstructorAnotherClass.invoke()
|
||||
}
|
||||
|
||||
public fun testLibraryFunctions() {
|
||||
val memberFunFromClass = { obj: String -> obj.length() }
|
||||
memberFunFromClass.invoke("str")
|
||||
}
|
||||
|
||||
public fun testOverloads() {
|
||||
val constructorWithoutParams = { Test.testOverloads() }
|
||||
constructorWithoutParams.invoke()
|
||||
|
||||
val constructorWithParam = { i: Int -> Test.testOverloads(i) }
|
||||
constructorWithParam.invoke(2)
|
||||
}
|
||||
|
||||
public fun testGenericFunctions() {
|
||||
val emptyList = { Collections.emptyList() }
|
||||
emptyList.invoke()
|
||||
}
|
||||
|
||||
public fun memberFun(): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
public fun staticFun(): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package test;
|
||||
|
||||
import javaApi.*;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
public static Java8Class field = new Java8Class();
|
||||
public static Java8Class staticFun() {
|
||||
return new Java8Class();
|
||||
}
|
||||
public int memberFun() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static String testOverloads() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
public static String testOverloads(int i) {
|
||||
return "2";
|
||||
}
|
||||
|
||||
public Test(int i) {
|
||||
super();
|
||||
}
|
||||
|
||||
public Test() {
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 {}
|
||||
|
||||
class Java8Class {
|
||||
private Java8Class field = new Java8Class();
|
||||
private MethodReferenceHelperClass h = new MethodReferenceHelperClass();
|
||||
|
||||
public void testStaticFunction() {
|
||||
JFunction0 staticFunFromSameClass = Java8Class::staticFun;
|
||||
staticFunFromSameClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Java8Class::staticFun);
|
||||
h.memberFun0(Java8Class::staticFun);
|
||||
|
||||
JFunction0 staticFunFromAnotherClass = Test::staticFun;
|
||||
staticFunFromAnotherClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Test::staticFun);
|
||||
h.memberFun0(Test::staticFun);
|
||||
}
|
||||
|
||||
public void testMemberFunctionThroughClass() {
|
||||
JFunction2<Java8Class, Integer> memberFunFromClass = Java8Class::memberFun;
|
||||
memberFunFromClass.foo(new Java8Class());
|
||||
MethodReferenceHelperClass.staticFun2(Java8Class::memberFun);
|
||||
h.memberFun2(Java8Class::memberFun);
|
||||
}
|
||||
|
||||
public void testMemberFunctionThroughObject() {
|
||||
Java8Class obj = new Java8Class();
|
||||
JFunction0 memberFunFromSameClass = obj::memberFun;
|
||||
memberFunFromSameClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(obj::memberFun);
|
||||
h.memberFun0(obj::memberFun);
|
||||
|
||||
Test anotherObj = new Test();
|
||||
JFunction0 memFunFromAnotherClass = anotherObj::memberFun;
|
||||
memFunFromAnotherClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(anotherObj::memberFun);
|
||||
h.memberFun0(anotherObj::memberFun);
|
||||
|
||||
JFunction0 memberFunThroughObj1 = field::memberFun;
|
||||
memberFunThroughObj1.foo();
|
||||
MethodReferenceHelperClass.staticFun0(field::memberFun);
|
||||
h.memberFun0(field::memberFun);
|
||||
|
||||
JFunction0 memberFunThroughObj2 = Test.field::memberFun;
|
||||
memberFunThroughObj2.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Test.field::memberFun);
|
||||
h.memberFun0(Test.field::memberFun);
|
||||
|
||||
JFunction0 memberFunThroughObj3 = Test.staticFun()::memberFun;
|
||||
memberFunThroughObj3.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Test.staticFun()::memberFun);
|
||||
h.memberFun0(Test.staticFun()::memberFun);
|
||||
}
|
||||
|
||||
public void testConstructor() {
|
||||
JFunction0 constructorSameClass = Java8Class::new;
|
||||
constructorSameClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Java8Class::new);
|
||||
h.memberFun0(Java8Class::new);
|
||||
|
||||
JFunction0 qualifiedConstructorSameClass = test.Java8Class::new;
|
||||
qualifiedConstructorSameClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(test.Java8Class::new);
|
||||
h.memberFun0(test.Java8Class::new);
|
||||
|
||||
JFunction0 constructorAnotherClass = Test::new;
|
||||
constructorAnotherClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Test::new);
|
||||
h.memberFun0(Test::new);
|
||||
|
||||
JFunction2<Integer, Test> constructorAnotherClassWithParam = Test::new;
|
||||
constructorAnotherClassWithParam.foo(1);
|
||||
MethodReferenceHelperClass.<Integer, Test>staticFun2(Test::new);
|
||||
h.<Integer, Test>memberFun2(Test::new);
|
||||
|
||||
JFunction0 qualifiedConstructorAnotherClass = test.Test::new;
|
||||
qualifiedConstructorAnotherClass.foo();
|
||||
MethodReferenceHelperClass.staticFun0(test.Test::new);
|
||||
h.memberFun0(test.Test::new);
|
||||
|
||||
JFunction0 constructorAnotherClassWithoutConstructor = Test2::new;
|
||||
constructorAnotherClassWithoutConstructor.foo();
|
||||
MethodReferenceHelperClass.staticFun0(Test2::new);
|
||||
h.memberFun0(Test2::new);
|
||||
}
|
||||
|
||||
public void testLibraryFunctions() {
|
||||
JFunction2<String, Integer> memberFunFromClass = String::length;
|
||||
memberFunFromClass.foo("str");
|
||||
|
||||
new Thread(System.out::println).start();
|
||||
((Runnable) System.out::println).run();
|
||||
}
|
||||
|
||||
public void testOverloads() {
|
||||
JFunction1<String> constructorWithoutParams = Test::testOverloads;
|
||||
constructorWithoutParams.foo();
|
||||
MethodReferenceHelperClass.<String>staticFun1(Test::testOverloads);
|
||||
h.<String>memberFun1(Test::testOverloads);
|
||||
|
||||
JFunction2<Integer, String> constructorWithParam = Test::testOverloads;
|
||||
constructorWithParam.foo(2);
|
||||
MethodReferenceHelperClass.<Integer, String>staticFun2(Test::testOverloads);
|
||||
h.<Integer, String>memberFun2(Test::testOverloads);
|
||||
}
|
||||
|
||||
public void testGenericFunctions() {
|
||||
JFunction1<List<String>> emptyList = Collections::emptyList;
|
||||
emptyList.foo();
|
||||
MethodReferenceHelperClass.<List<String>>staticFun1(Collections::emptyList);
|
||||
h.<List<String>>memberFun1(Collections::emptyList);
|
||||
}
|
||||
|
||||
public static int staticFun() { return 1; }
|
||||
|
||||
public int memberFun() { return 1; }
|
||||
|
||||
public Java8Class() {}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package test
|
||||
|
||||
import javaApi.*
|
||||
import java.util.Collections
|
||||
|
||||
class Test {
|
||||
public fun memberFun(): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
public constructor(i: Int) : super() {
|
||||
}
|
||||
|
||||
public constructor() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
public var field: Java8Class = Java8Class()
|
||||
public fun staticFun(): Java8Class {
|
||||
return Java8Class()
|
||||
}
|
||||
|
||||
public fun testOverloads(): String {
|
||||
return "1"
|
||||
}
|
||||
|
||||
public fun testOverloads(i: Int): String {
|
||||
return "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Test2
|
||||
|
||||
class Java8Class {
|
||||
private val field = Java8Class()
|
||||
private val h = MethodReferenceHelperClass()
|
||||
|
||||
public fun testStaticFunction() {
|
||||
val staticFunFromSameClass = JFunction0 { staticFun() }
|
||||
staticFunFromSameClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { staticFun() }
|
||||
h.memberFun0 { staticFun() }
|
||||
|
||||
val staticFunFromAnotherClass = JFunction0 { Test.staticFun() }
|
||||
staticFunFromAnotherClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Test.staticFun() }
|
||||
h.memberFun0 { Test.staticFun() }
|
||||
}
|
||||
|
||||
public fun testMemberFunctionThroughClass() {
|
||||
val memberFunFromClass = JFunction2<Java8Class, Int> { it.memberFun() }
|
||||
memberFunFromClass.foo(Java8Class())
|
||||
MethodReferenceHelperClass.staticFun2(JFunction2<Any, Any> { memberFun() })
|
||||
h.memberFun2(JFunction2<Any, Any> { memberFun() })
|
||||
}
|
||||
|
||||
public fun testMemberFunctionThroughObject() {
|
||||
val obj = Java8Class()
|
||||
val memberFunFromSameClass = JFunction0 { obj.memberFun() }
|
||||
memberFunFromSameClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { obj.memberFun() }
|
||||
h.memberFun0 { obj.memberFun() }
|
||||
|
||||
val anotherObj = Test()
|
||||
val memFunFromAnotherClass = JFunction0 { anotherObj.memberFun() }
|
||||
memFunFromAnotherClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { anotherObj.memberFun() }
|
||||
h.memberFun0 { anotherObj.memberFun() }
|
||||
|
||||
val memberFunThroughObj1 = JFunction0 { field.memberFun() }
|
||||
memberFunThroughObj1.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { field.memberFun() }
|
||||
h.memberFun0 { field.memberFun() }
|
||||
|
||||
val memberFunThroughObj2 = JFunction0 { Test.field.memberFun() }
|
||||
memberFunThroughObj2.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Test.field.memberFun() }
|
||||
h.memberFun0 { Test.field.memberFun() }
|
||||
|
||||
val memberFunThroughObj3 = JFunction0 { Test.staticFun().memberFun() }
|
||||
memberFunThroughObj3.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Test.staticFun().memberFun() }
|
||||
h.memberFun0 { Test.staticFun().memberFun() }
|
||||
}
|
||||
|
||||
public fun testConstructor() {
|
||||
val constructorSameClass = JFunction0 { Java8Class() }
|
||||
constructorSameClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Java8Class() }
|
||||
h.memberFun0 { Java8Class() }
|
||||
|
||||
val qualifiedConstructorSameClass = JFunction0 { test.Java8Class() }
|
||||
qualifiedConstructorSameClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { test.Java8Class() }
|
||||
h.memberFun0 { test.Java8Class() }
|
||||
|
||||
val constructorAnotherClass = JFunction0 { Test() }
|
||||
constructorAnotherClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Test() }
|
||||
h.memberFun0 { Test() }
|
||||
|
||||
val constructorAnotherClassWithParam = JFunction2<Int, Test> { Test(it) }
|
||||
constructorAnotherClassWithParam.foo(1)
|
||||
MethodReferenceHelperClass.staticFun2(JFunction2<Int, Test> { Test(it) })
|
||||
h.memberFun2(JFunction2<Int, Test> { Test(it) })
|
||||
|
||||
val qualifiedConstructorAnotherClass = JFunction0 { test.Test() }
|
||||
qualifiedConstructorAnotherClass.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { test.Test() }
|
||||
h.memberFun0 { test.Test() }
|
||||
|
||||
val constructorAnotherClassWithoutConstructor = JFunction0 { Test2() }
|
||||
constructorAnotherClassWithoutConstructor.foo()
|
||||
MethodReferenceHelperClass.staticFun0 { Test2() }
|
||||
h.memberFun0 { Test2() }
|
||||
}
|
||||
|
||||
public fun testLibraryFunctions() {
|
||||
val memberFunFromClass = JFunction2<String, Int> { it.length() }
|
||||
memberFunFromClass.foo("str")
|
||||
|
||||
Thread(Runnable { System.out.println() }).start()
|
||||
Runnable { System.out.println() }.run()
|
||||
}
|
||||
|
||||
public fun testOverloads() {
|
||||
val constructorWithoutParams = JFunction1 { Test.testOverloads() }
|
||||
constructorWithoutParams.foo()
|
||||
MethodReferenceHelperClass.staticFun1 { Test.testOverloads() }
|
||||
h.memberFun1 { Test.testOverloads() }
|
||||
|
||||
val constructorWithParam = JFunction2<Int, String> { Test.testOverloads(it) }
|
||||
constructorWithParam.foo(2)
|
||||
MethodReferenceHelperClass.staticFun2(JFunction2<Int, String> { Test.testOverloads(it) })
|
||||
h.memberFun2(JFunction2<Int, String> { Test.testOverloads(it) })
|
||||
}
|
||||
|
||||
public fun testGenericFunctions() {
|
||||
val emptyList = JFunction1<List<String>> { Collections.emptyList() }
|
||||
emptyList.foo()
|
||||
MethodReferenceHelperClass.staticFun1(JFunction1<List<String>> { Collections.emptyList() })
|
||||
h.memberFun1(JFunction1<List<String>> { Collections.emptyList() })
|
||||
}
|
||||
|
||||
public fun memberFun(): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
public fun staticFun(): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,11 @@ class C {
|
||||
c.instanceMethod();
|
||||
ClassWithStatics.staticField += 2;
|
||||
}
|
||||
|
||||
void methodReferences() {
|
||||
JFunction1ReturnType<Integer> staticMethod = ClassWithStatics::staticMethod;
|
||||
JFunction1ReturnType<ClassWithStatics> instanceMethod = ClassWithStatics::instanceMethod;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends ClassWithStatics {
|
||||
|
||||
@@ -6,6 +6,11 @@ class C {
|
||||
c.instanceMethod();
|
||||
ClassWithStatics.staticField += 2;
|
||||
}
|
||||
|
||||
void methodReferences() {
|
||||
JFunction1ReturnType<Integer> staticMethod = ClassWithStatics.Companion::staticMethod;
|
||||
JFunction1ReturnType<ClassWithStatics> instanceMethod = ClassWithStatics::instanceMethod;
|
||||
}
|
||||
}
|
||||
|
||||
class D extends ClassWithStatics {
|
||||
|
||||
@@ -2254,6 +2254,18 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("java8MRKFunctionExpectedType.java")
|
||||
public void testJava8MRKFunctionExpectedType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/java8MRKFunctionExpectedType.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("java8MRSamConstructor.java")
|
||||
public void testJava8MRSamConstructor() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/java8MRSamConstructor.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lineBreaksBetweenParameters.java")
|
||||
public void testLineBreaksBetweenParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/lineBreaksBetweenParameters.java");
|
||||
|
||||
@@ -2254,6 +2254,18 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("java8MRKFunctionExpectedType.java")
|
||||
public void testJava8MRKFunctionExpectedType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/java8MRKFunctionExpectedType.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("java8MRSamConstructor.java")
|
||||
public void testJava8MRSamConstructor() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/java8MRSamConstructor.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lineBreaksBetweenParameters.java")
|
||||
public void testLineBreaksBetweenParameters() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/function/lineBreaksBetweenParameters.java");
|
||||
|
||||
Reference in New Issue
Block a user