Support equals, hashCode, toString for ::-references without reflection
This commit is contained in:
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// NO_KOTLIN_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class M {
|
||||||
|
fun foo() {}
|
||||||
|
val bar = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkEquals(x: KCallable<*>, y: KCallable<*>) {
|
||||||
|
assertEquals(x, y)
|
||||||
|
assertEquals(y, x)
|
||||||
|
assertEquals(x.hashCode(), y.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkToString(x: KCallable<*>, expected: String) {
|
||||||
|
assertEquals(expected + " (Kotlin reflection is not available)", x.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
checkEquals(M::foo, M::foo)
|
||||||
|
checkEquals(M::bar, M::bar)
|
||||||
|
checkEquals(::M, ::M)
|
||||||
|
|
||||||
|
checkToString(M::foo, "function foo")
|
||||||
|
checkToString(M::bar, "property bar")
|
||||||
|
checkToString(::M, "constructor")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+24
@@ -0,0 +1,24 @@
|
|||||||
|
// NO_KOTLIN_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class M
|
||||||
|
|
||||||
|
fun check(x: KClass<*>) {
|
||||||
|
assertEquals(x, x.java.kotlin)
|
||||||
|
assertEquals(x.hashCode(), x.java.kotlin.hashCode())
|
||||||
|
assertEquals(x.java.toString() + " (Kotlin reflection is not available)", x.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
check(M::class)
|
||||||
|
check(String::class)
|
||||||
|
check(Error::class)
|
||||||
|
check(Int::class)
|
||||||
|
check(java.lang.Integer::class)
|
||||||
|
check(MutableList::class)
|
||||||
|
check(Array<String>::class)
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+21
@@ -4022,6 +4022,27 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/simpleClassLiterals.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/simpleClassLiterals.kt");
|
||||||
doTestWithStdlib(fileName);
|
doTestWithStdlib(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/methodsFromAny")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class MethodsFromAny extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInMethodsFromAny() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableReferences.kt")
|
||||||
|
public void testCallableReferences() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/methodsFromAny/callableReferences.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classReference.kt")
|
||||||
|
public void testClassReference() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/noKotlinReflect/methodsFromAny/classReference.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/parameters")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/parameters")
|
||||||
|
|||||||
@@ -43,4 +43,13 @@ public class ClassReference(override val jClass: Class<*>) : KClass<Any>, ClassB
|
|||||||
get() = error()
|
get() = error()
|
||||||
|
|
||||||
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
|
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
|
||||||
|
|
||||||
|
override fun equals(other: Any?) =
|
||||||
|
other is ClassReference && jClass == other.jClass
|
||||||
|
|
||||||
|
override fun hashCode() =
|
||||||
|
jClass.hashCode()
|
||||||
|
|
||||||
|
override fun toString() =
|
||||||
|
jClass.toString() + Reflection.REFLECTION_NOT_AVAILABLE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,4 +79,28 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
|||||||
protected static Error error() {
|
protected static Error error() {
|
||||||
throw new KotlinReflectionNotSupportedError();
|
throw new KotlinReflectionNotSupportedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (!(obj instanceof FunctionReference)) return false;
|
||||||
|
|
||||||
|
FunctionReference other = (FunctionReference) obj;
|
||||||
|
return getOwner().equals(other.getOwner()) &&
|
||||||
|
getName().equals(other.getName()) &&
|
||||||
|
getSignature().equals(other.getSignature());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (getOwner().hashCode() * 31 + getName().hashCode()) * 31 + getSignature().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
// TODO: consider adding the class name to toString() for constructors
|
||||||
|
return "<init>".equals(getName())
|
||||||
|
? "constructor" + Reflection.REFLECTION_NOT_AVAILABLE
|
||||||
|
: "function " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,24 @@ package kotlin.jvm.internal;
|
|||||||
import kotlin.reflect.KProperty;
|
import kotlin.reflect.KProperty;
|
||||||
|
|
||||||
public abstract class PropertyReference extends CallableReference implements KProperty {
|
public abstract class PropertyReference extends CallableReference implements KProperty {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (!(obj instanceof PropertyReference)) return false;
|
||||||
|
|
||||||
|
PropertyReference other = (PropertyReference) obj;
|
||||||
|
return getOwner().equals(other.getOwner()) &&
|
||||||
|
getName().equals(other.getName()) &&
|
||||||
|
getSignature().equals(other.getSignature());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (getOwner().hashCode() * 31 + getName().hashCode()) * 31 + getSignature().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "property " + getName() + Reflection.REFLECTION_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public class Reflection {
|
|||||||
factory = impl != null ? impl : new ReflectionFactory();
|
factory = impl != null ? impl : new ReflectionFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ static final String REFLECTION_NOT_AVAILABLE = " (Kotlin reflection is not available)";
|
||||||
|
|
||||||
private static final KClass[] EMPTY_K_CLASS_ARRAY = new KClass[0];
|
private static final KClass[] EMPTY_K_CLASS_ARRAY = new KClass[0];
|
||||||
|
|
||||||
public static KClass createKotlinClass(Class javaClass) {
|
public static KClass createKotlinClass(Class javaClass) {
|
||||||
|
|||||||
Reference in New Issue
Block a user