From 50ff2a3ad2ad5c78c1cd94f59bfe3c936286f9e2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 14 Sep 2015 17:14:16 +0300 Subject: [PATCH] Multifile facade should contain reflection data, otherwise callable references to stdlib functions will not work in the migration scheme. --- .../kotlin/codegen/MultifileClassCodegen.kt | 17 ++++++++++++++++- .../reflection/functions/functionFromStdlib.kt | 5 +++++ .../BlackBoxWithStdlibCodegenTestGenerated.java | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/functions/functionFromStdlib.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt index 2d32ff7b5e3..3d7291a0594 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.fileClasses.getFileClassType +import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.PackageParts import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider @@ -35,9 +36,13 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.MemberComparator +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import java.util.* @@ -111,6 +116,7 @@ public class MultifileClassCodegen( tasks: Map Unit>, partFqNames: List ) { + generateKotlinPackageReflectionField() MemberCodegen.generateModuleNameField(state, classBuilder) for (member in tasks.keySet().sortedWith(MemberComparator.INSTANCE)) { @@ -150,7 +156,6 @@ public class MultifileClassCodegen( } } else if (declaration is JetScript) { - // SCRIPT: generate script code, should be separate execution branch if (state.generateDeclaredClassFilter.shouldGenerateScript(declaration)) { ScriptCodegen.createScriptCodegen(declaration, state, partContext).generate() @@ -182,6 +187,16 @@ public class MultifileClassCodegen( } } + private fun generateKotlinPackageReflectionField() { + val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "", "()V", null, null) + val method = AsmUtil.method("createKotlinPackage", + AsmTypes.K_PACKAGE_TYPE, AsmTypes.getType(Class::class.java), AsmTypes.getType(String::class.java)) + val iv = InstructionAdapter(mv) + MemberCodegen.generateReflectionObjectField(state, facadeClassType, classBuilder, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv) + iv.areturn(Type.VOID_TYPE) + FunctionCodegen.endVisit(mv, "package facade static initializer", null) + } + private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List) { if (state.classBuilderMode != ClassBuilderMode.FULL) return if (files.any { it.isScript }) return diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/functions/functionFromStdlib.kt b/compiler/testData/codegen/boxWithStdlib/reflection/functions/functionFromStdlib.kt new file mode 100644 index 00000000000..472d2475e58 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/functions/functionFromStdlib.kt @@ -0,0 +1,5 @@ +fun doStuff(fn: String.() -> String) = "ok".fn() + +fun box(): String { + return doStuff(String::toUpperCase) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 2a5517e81a3..8f25a002e64 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -3381,6 +3381,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/functions"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("functionFromStdlib.kt") + public void testFunctionFromStdlib() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/functions/functionFromStdlib.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("localFunctionName.kt") public void testLocalFunctionName() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/functions/localFunctionName.kt");