Reflection support

This commit is contained in:
Michael Bogdanov
2015-08-25 17:50:32 +03:00
parent 357a6d9902
commit e83ec1017b
16 changed files with 107 additions and 14 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.common;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
@@ -38,6 +38,8 @@ import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getMappingFileName;
public class ClassFileFactory implements OutputFileCollection {
private final GenerationState state;
private final ClassBuilderFactory builderFactory;
@@ -86,7 +88,7 @@ public class ClassFileFactory implements OutputFileCollection {
private void writeModuleMappings(Collection<PackageCodegen> values) {
String moduleName = KotlinPackage.removeSurrounding(state.getModule().getName().asString(), "<", ">");
String outputFilePath = "META-INF/" + moduleName + ".kotlin_module";
String outputFilePath = getMappingFileName(moduleName);
final StringWriter moduleMapping = new StringWriter(1024);
for (PackageCodegen codegen : values) {
codegen.getFacades().serialize(moduleMapping);
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
@@ -32,6 +34,15 @@ public class GeneratedClassLoader extends URLClassLoader {
this.factory = factory;
}
@Override
public InputStream getResourceAsStream(String name) {
OutputFile outputFile = factory.get(name);
if (outputFile != null) {
return new ByteArrayInputStream(outputFile.asByteArray());
}
return super.getResourceAsStream(name);
}
@NotNull
@Override
protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {
@@ -245,4 +245,13 @@ public class JvmCodegenUtil {
module == module.getBuiltIns().getBuiltInsModule() ||
DescriptorUtils.isAnnotationClass(descriptor);
}
public static String getModuleName(ModuleDescriptor module) {
return KotlinPackage.removeSurrounding(module.getName().asString(), "<", ">");
}
@NotNull
public static String getMappingFileName(@NotNull String moduleName) {
return "META-INF/" + moduleName + ".kotlin_module";
}
}
@@ -467,6 +467,9 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
v.aconst(thisAsmType);
if (factory.getArgumentTypes().length == 2) {
v.aconst(JvmCodegenUtil.getModuleName(state.getModule()));
}
v.invokestatic(REFLECTION, factory.getName(), factory.getDescriptor(), false);
v.putstatic(thisAsmType.getInternalName(), fieldName, type);
}
@@ -260,7 +260,7 @@ public class PackageCodegen {
private void generateKotlinPackageReflectionField() {
MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_STATIC, "<clinit>", "()V", null, null);
Method method = method("createKotlinPackage", K_PACKAGE_TYPE, getType(Class.class));
Method method = method("createKotlinPackage", K_PACKAGE_TYPE, getType(Class.class), getType(String.class));
InstructionAdapter iv = new InstructionAdapter(mv);
MemberCodegen.generateReflectionObjectField(state, packageClassType, v, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv);
iv.areturn(Type.VOID_TYPE);
@@ -82,7 +82,7 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
val classLoader = URLClassLoader(arrayOf(tmpdir.toURI().toURL()), ForTestCompileRuntime.runtimeAndReflectJarClassLoader())
val actual = createReflectedPackageView(classLoader)
val actual = createReflectedPackageView(classLoader, "")
val expected = LoadDescriptorUtil.loadTestPackageAndBindingContextFromJavaRoot(
tmpdir, getTestRootDisposable(), jdkKind, ConfigurationKind.ALL, true
@@ -129,8 +129,8 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
}
}
private fun createReflectedPackageView(classLoader: URLClassLoader): SyntheticPackageViewForTest {
val module = RuntimeModuleData.create(classLoader).module
private fun createReflectedPackageView(classLoader: URLClassLoader, moduleName: String): SyntheticPackageViewForTest {
val module = RuntimeModuleData.create(classLoader, moduleName).module
val generatedPackageDir = File(tmpdir, LoadDescriptorUtil.TEST_PACKAGE_FQNAME.pathSegments().single().asString())