Support mapping between Java and Kotlin reflection objects

This commit is contained in:
Alexander Udalov
2014-06-20 19:22:02 +04:00
parent c575ad9fb0
commit 704de8992e
33 changed files with 434 additions and 93 deletions
@@ -61,6 +61,7 @@ public class SpecialFiles {
excludedFiles.add("boxMultiFile"); // MultiFileTest not supported yet
excludedFiles.add("boxInline"); // MultiFileTest not supported yet
excludedFiles.add("reflection");
excludedFiles.add("kt3238.kt"); // Reflection
excludedFiles.add("kt1482_2279.kt"); // Reflection
@@ -69,11 +70,6 @@ public class SpecialFiles {
excludedFiles.add("packageQualifiedMethod.kt"); // Cannot change package name
excludedFiles.add("classObjectToString.kt"); // Cannot change package name
/* Reflection tests with full-qualified names*/
excludedFiles.add("insideLambda");
excludedFiles.add("lambda");
excludedFiles.add("kt5112.kt");
excludedFiles.add("kt326.kt"); // Commented
excludedFiles.add("kt1213.kt"); // Commented
@@ -0,0 +1 @@
public class jClass2kClass {}
@@ -0,0 +1,11 @@
import jClass2kClass as J
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
fun box(): String {
val j = javaClass<J>()
assertEquals(j, j.kotlin.java)
return "OK"
}
@@ -0,0 +1,9 @@
public class javaFields {
public final int i;
public String s;
public javaFields(int i, String s) {
this.i = i;
this.s = s;
}
}
@@ -0,0 +1,43 @@
import javaFields as J
import java.lang.reflect.*
import kotlin.reflect.*
import kotlin.reflect.jvm.*
fun box(): String {
val i = J::i
val s = J::s
// Check that correct reflection objects are created
assert(i.javaClass.getSimpleName() == "KForeignMemberProperty", "Fail i class")
assert(s.javaClass.getSimpleName() == "KMutableForeignMemberProperty", "Fail s class")
// Check that no Method objects are created for such properties
assert(i.javaGetter == null, "Fail i getter")
assert(s.javaGetter == null, "Fail s getter")
assert(s.javaSetter == null, "Fail s setter")
// Check that correct Field objects are created
val ji = i.javaField!!
val js = s.javaField!!
assert(Modifier.isFinal(ji.getModifiers()), "Fail i final")
assert(!Modifier.isFinal(js.getModifiers()), "Fail s final")
// Check that those Field objects work as expected
val a = J(42, "abc")
assert(ji.get(a) == 42, "Fail ji get")
assert(js.get(a) == "abc", "Fail js get")
js.set(a, "def")
assert(js.get(a) == "def", "Fail js set")
assert(a.s == "def", "Fail js access")
// Check that valid Kotlin reflection objects are created by those Field objects
val ki = ji.kotlin as KMemberProperty<J, Int>
val ks = js.kotlin as KMutableMemberProperty<J, String>
assert(ki.get(a) == 42, "Fail ki get")
assert(ks.get(a) == "def", "Fail ks get")
ks.set(a, "ghi")
assert(ks.get(a) == "ghi", "Fail ks set")
return "OK"
}
@@ -0,0 +1,27 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
class K(var value: Long)
var K.ext: Double
get() = value.toDouble()
set(value) {
this.value = value.toLong()
}
fun box(): String {
val p = K::ext
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, Class.forName("_DefaultPackage").getMethod("getExt", javaClass<K>()))
assertEquals(setter, Class.forName("_DefaultPackage").getMethod("setExt", javaClass<K>(), javaClass<Double>()))
val k = K(42L)
assert(getter.invoke(null, k) == 42.0, "Fail k getter")
setter.invoke(null, k, -239.0)
assert(getter.invoke(null, k) == -239.0, "Fail k setter")
return "OK"
}
@@ -0,0 +1,23 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
class K(var value: Long)
fun box(): String {
val p = K::value
assert(p.javaField != null, "Fail p field")
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, javaClass<K>().getMethod("getValue"))
assertEquals(setter, javaClass<K>().getMethod("setValue", javaClass<Long>()))
val k = K(42L)
assert(getter.invoke(k) == 42L, "Fail k getter")
setter.invoke(k, -239L)
assert(getter.invoke(k) == -239L, "Fail k setter")
return "OK"
}
@@ -0,0 +1,13 @@
package test
import kotlin.reflect.jvm.*
import kotlin.test.*
fun box(): String {
val facadeJClass = Class.forName("test.TestPackage") as Class<Any>
assertEquals(facadeJClass, facadeJClass.kotlinPackage.javaFacade)
assertEquals(facadeJClass, facadeJClass.kotlin.java)
return "OK"
}
@@ -0,0 +1,23 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
var topLevel = "123"
fun box(): String {
val p = ::topLevel
// TODO: uncomment when fields are loaded from package parts
// assert(p.javaField != null, "Fail p field")
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, Class.forName("_DefaultPackage").getMethod("getTopLevel"))
assertEquals(setter, Class.forName("_DefaultPackage").getMethod("setTopLevel", javaClass<String>()))
assert(getter.invoke(null) == "123", "Fail k getter")
setter.invoke(null, "456")
assert(getter.invoke(null) == "456", "Fail k setter")
return "OK"
}
@@ -97,7 +97,8 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
File javaClassesTempDirectory = compileJava(ktFile.replaceFirst("\\.kt$", ".java"));
myEnvironment = JetCoreEnvironment.createForTests(getTestRootDisposable(), JetTestUtils.compilerConfigurationForTests(
ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), javaClassesTempDirectory));
ConfigurationKind.ALL, TestJdkKind.FULL_JDK, JetTestUtils.getAnnotationsJar(), javaClassesTempDirectory
));
loadFile(ktFile);
blackBox();
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxAgainstJava")
@InnerTestClasses({BlackBoxAgainstJavaCodegenTestGenerated.Annotations.class, BlackBoxAgainstJavaCodegenTestGenerated.CallableReference.class, BlackBoxAgainstJavaCodegenTestGenerated.Constructor.class, BlackBoxAgainstJavaCodegenTestGenerated.Delegation.class, BlackBoxAgainstJavaCodegenTestGenerated.Enum.class, BlackBoxAgainstJavaCodegenTestGenerated.Functions.class, BlackBoxAgainstJavaCodegenTestGenerated.InnerClass.class, BlackBoxAgainstJavaCodegenTestGenerated.Property.class, BlackBoxAgainstJavaCodegenTestGenerated.Sam.class, BlackBoxAgainstJavaCodegenTestGenerated.StaticFun.class, BlackBoxAgainstJavaCodegenTestGenerated.Visibility.class})
@InnerTestClasses({BlackBoxAgainstJavaCodegenTestGenerated.Annotations.class, BlackBoxAgainstJavaCodegenTestGenerated.CallableReference.class, BlackBoxAgainstJavaCodegenTestGenerated.Constructor.class, BlackBoxAgainstJavaCodegenTestGenerated.Delegation.class, BlackBoxAgainstJavaCodegenTestGenerated.Enum.class, BlackBoxAgainstJavaCodegenTestGenerated.Functions.class, BlackBoxAgainstJavaCodegenTestGenerated.InnerClass.class, BlackBoxAgainstJavaCodegenTestGenerated.Property.class, BlackBoxAgainstJavaCodegenTestGenerated.Reflection.class, BlackBoxAgainstJavaCodegenTestGenerated.Sam.class, BlackBoxAgainstJavaCodegenTestGenerated.StaticFun.class, BlackBoxAgainstJavaCodegenTestGenerated.Visibility.class})
public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBoxAgainstJava() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxAgainstJava"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -236,6 +236,39 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxCod
}
@TestMetadata("compiler/testData/codegen/boxAgainstJava/reflection")
@InnerTestClasses({Reflection.Mapping.class})
public static class Reflection extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInReflection() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxAgainstJava/reflection"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("compiler/testData/codegen/boxAgainstJava/reflection/mapping")
public static class Mapping extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInMapping() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxAgainstJava/reflection/mapping"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("jClass2kClass.kt")
public void testJClass2kClass() throws Exception {
doTestAgainstJava("compiler/testData/codegen/boxAgainstJava/reflection/mapping/jClass2kClass.kt");
}
@TestMetadata("javaFields.kt")
public void testJavaFields() throws Exception {
doTestAgainstJava("compiler/testData/codegen/boxAgainstJava/reflection/mapping/javaFields.kt");
}
}
public static Test innerSuite() {
TestSuite suite = new TestSuite("Reflection");
suite.addTestSuite(Reflection.class);
suite.addTestSuite(Mapping.class);
return suite;
}
}
@TestMetadata("compiler/testData/codegen/boxAgainstJava/sam")
@InnerTestClasses({Sam.Adapters.class})
public static class Sam extends AbstractBlackBoxCodegenTest {
@@ -609,6 +642,7 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxCod
suite.addTestSuite(Functions.class);
suite.addTestSuite(InnerClass.class);
suite.addTestSuite(Property.class);
suite.addTest(Reflection.innerSuite());
suite.addTest(Sam.innerSuite());
suite.addTestSuite(StaticFun.class);
suite.addTest(Visibility.innerSuite());
@@ -1381,99 +1381,151 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection")
@InnerTestClasses({Reflection.InsideLambda.class, Reflection.Lambda.class})
@InnerTestClasses({Reflection.Enclosing.class, Reflection.GenericSignature.class, Reflection.Mapping.class})
public static class Reflection extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInReflection() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("kt5112.kt")
public void testKt5112() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/kt5112.kt");
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing")
@InnerTestClasses({Enclosing.InsideLambda.class, Enclosing.Lambda.class})
public static class Enclosing extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInEnclosing() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/enclosing"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/insideLambda")
public static class InsideLambda extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInInsideLambda() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/insideLambda"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("classInLambda.kt")
public void testClassInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/insideLambda/classInLambda.kt");
}
@TestMetadata("objectInLambda.kt")
public void testObjectInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/insideLambda/objectInLambda.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda")
public static class Lambda extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInLambda() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("lambdaInConstructor.kt")
public void testLambdaInConstructor() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInConstructor.kt");
}
@TestMetadata("lambdaInFunction.kt")
public void testLambdaInFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInFunction.kt");
}
@TestMetadata("lambdaInLambda.kt")
public void testLambdaInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInLambda.kt");
}
@TestMetadata("lambdaInLocalClass.kt")
public void testLambdaInLocalClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInLocalClass.kt");
}
@TestMetadata("lambdaInLocalFunction.kt")
public void testLambdaInLocalFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInLocalFunction.kt");
}
@TestMetadata("lambdaInMemberFunction.kt")
public void testLambdaInMemberFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInMemberFunction.kt");
}
@TestMetadata("lambdaInMemberFunctionInLocalClass.kt")
public void testLambdaInMemberFunctionInLocalClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInMemberFunctionInLocalClass.kt");
}
@TestMetadata("lambdaInMemberFunctionInNestedClass.kt")
public void testLambdaInMemberFunctionInNestedClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInMemberFunctionInNestedClass.kt");
}
@TestMetadata("lambdaInObjectExpression.kt")
public void testLambdaInObjectExpression() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInObjectExpression.kt");
}
@TestMetadata("lambdaInPackage.kt")
public void testLambdaInPackage() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInPackage.kt");
}
@TestMetadata("lambdaInPropertyGetter.kt")
public void testLambdaInPropertyGetter() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInPropertyGetter.kt");
}
@TestMetadata("lambdaInPropertySetter.kt")
public void testLambdaInPropertySetter() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInPropertySetter.kt");
}
}
public static Test innerSuite() {
TestSuite suite = new TestSuite("Enclosing");
suite.addTestSuite(Enclosing.class);
suite.addTestSuite(InsideLambda.class);
suite.addTestSuite(Lambda.class);
return suite;
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda")
public static class InsideLambda extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInInsideLambda() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda"), Pattern.compile("^(.+)\\.kt$"), true);
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature")
public static class GenericSignature extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInGenericSignature() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("classInLambda.kt")
public void testClassInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt");
}
@TestMetadata("objectInLambda.kt")
public void testObjectInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt");
@TestMetadata("kt5112.kt")
public void testKt5112() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt5112.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/lambda")
public static class Lambda extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInLambda() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/lambda"), Pattern.compile("^(.+)\\.kt$"), true);
@TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping")
public static class Mapping extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInMapping() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/mapping"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("lambdaInConstructor.kt")
public void testLambdaInConstructor() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt");
@TestMetadata("extensionProperty.kt")
public void testExtensionProperty() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/mapping/extensionProperty.kt");
}
@TestMetadata("lambdaInFunction.kt")
public void testLambdaInFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt");
@TestMetadata("memberProperty.kt")
public void testMemberProperty() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/mapping/memberProperty.kt");
}
@TestMetadata("lambdaInLambda.kt")
public void testLambdaInLambda() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt");
@TestMetadata("package.kt")
public void testPackage() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/mapping/package.kt");
}
@TestMetadata("lambdaInLocalClass.kt")
public void testLambdaInLocalClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt");
}
@TestMetadata("lambdaInLocalFunction.kt")
public void testLambdaInLocalFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt");
}
@TestMetadata("lambdaInMemberFunction.kt")
public void testLambdaInMemberFunction() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt");
}
@TestMetadata("lambdaInMemberFunctionInLocalClass.kt")
public void testLambdaInMemberFunctionInLocalClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt");
}
@TestMetadata("lambdaInMemberFunctionInNestedClass.kt")
public void testLambdaInMemberFunctionInNestedClass() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt");
}
@TestMetadata("lambdaInObjectExpression.kt")
public void testLambdaInObjectExpression() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt");
}
@TestMetadata("lambdaInPackage.kt")
public void testLambdaInPackage() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt");
}
@TestMetadata("lambdaInPropertyGetter.kt")
public void testLambdaInPropertyGetter() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt");
}
@TestMetadata("lambdaInPropertySetter.kt")
public void testLambdaInPropertySetter() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt");
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/mapping/topLevelProperty.kt");
}
}
@@ -1481,8 +1533,9 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
public static Test innerSuite() {
TestSuite suite = new TestSuite("Reflection");
suite.addTestSuite(Reflection.class);
suite.addTestSuite(InsideLambda.class);
suite.addTestSuite(Lambda.class);
suite.addTest(Enclosing.innerSuite());
suite.addTestSuite(GenericSignature.class);
suite.addTestSuite(Mapping.class);
return suite;
}
}