Fix reflection on top level declarations from other modules

The main problem here is that moduleName that is being passed to KPackageImpl
is useless: as can be seen in
ClosureCodegen.generateCallableReferenceDeclarationContainer, the name of the
current module is always written to the class file for a callable reference,
not the name of the module of the referenced declaration. This resulted in
reflection not loading the correct .kotlin_module file and subsequently not
finding the required file facade for a top-level function.

The commit does not fix the issue with the incorrect module name written in the
back-end, but workarounds it. It turns out, reflection can figure out the name
of the module of the referenced declaration itself by parsing the header from
the given java.lang.Class object for a single-file/multi-file package facade
and extract the package_module_name protobuf extension. Similar code was
already there in Member.getKPackage() in ReflectJvmMapping.kt but it did not
support multi-file classes, of which there are a lot in the standard library;
this is now supported

 #KT-12630 Fixed
 #KT-14731 Fixed
This commit is contained in:
Alexander Udalov
2017-02-03 18:48:03 +03:00
parent 8a79482c5c
commit 6d16ea0a3a
14 changed files with 144 additions and 29 deletions
@@ -16859,7 +16859,13 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
@TestMetadata("functionFromStdlib.kt")
public void testFunctionFromStdlib() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/functionFromStdlib.kt");
doTest(fileName);
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
}
@TestMetadata("functionReferenceErasedToKFunction.kt")
@@ -17645,6 +17651,30 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
}
@TestMetadata("functionFromStdlibMultiFileFacade.kt")
public void testFunctionFromStdlibMultiFileFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/methodsFromAny/functionFromStdlibMultiFileFacade.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
}
@TestMetadata("functionFromStdlibSingleFileFacade.kt")
public void testFunctionFromStdlibSingleFileFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/methodsFromAny/functionFromStdlibSingleFileFacade.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
}
@TestMetadata("functionToString.kt")
public void testFunctionToString() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/methodsFromAny/functionToString.kt");