Multifile facade should contain reflection data,

otherwise callable references to stdlib functions will not work in the migration scheme.
This commit is contained in:
Dmitry Petrov
2015-09-14 17:14:16 +03:00
parent 5d0243d46f
commit 50ff2a3ad2
3 changed files with 27 additions and 1 deletions
@@ -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<CallableMemberDescriptor, () -> Unit>,
partFqNames: List<FqName>
) {
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, "<clinit>", "()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<FqName>) {
if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) return
@@ -0,0 +1,5 @@
fun doStuff(fn: String.() -> String) = "ok".fn()
fun box(): String {
return doStuff(String::toUpperCase)
}
@@ -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");