Write module name to metadata, fix reflection for file facades

Module name will be used for proper introspection of internal members
This commit is contained in:
Alexander Udalov
2015-10-11 15:23:14 +03:00
parent 0218e0351b
commit 9e4823ef82
18 changed files with 42 additions and 12 deletions
@@ -836,9 +836,10 @@ public class AsmUtil {
}
}
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v) {
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
AnnotationVisitor av = v.newAnnotation(Type.getObjectType(KotlinSyntheticClass.CLASS_NAME.getInternalName()).getDescriptor(), true);
JvmCodegenUtil.writeAbiVersion(av);
JvmCodegenUtil.writeModuleName(av, state);
av.visitEnd();
}
@@ -57,6 +57,7 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLiteralReference;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
@@ -218,7 +219,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
@Override
protected void generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v);
writeKotlinSyntheticClassAnnotation(v, state);
DescriptorSerializer serializer =
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), typeMapper));
@@ -227,6 +228,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CALLABLE), true);
writeAnnotationData(av, serializer, functionProto);
writeModuleName(av, state);
av.visitEnd();
}
@@ -264,6 +264,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
writeAnnotationData(av, serializer, classProto);
writeModuleName(av, state);
av.visitEnd();
}
@@ -279,7 +280,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private static Map<String, String> KOTLIN_MARKER_INTERFACES = new HashMap<String, String>();
private static final Map<String, String> KOTLIN_MARKER_INTERFACES = new HashMap<String, String>();
static {
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterator", "kotlin/jvm/internal/markers/KMappedMarker");
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterable", "kotlin/jvm/internal/markers/KMappedMarker");
@@ -148,6 +148,6 @@ public class InterfaceImplBodyCodegen(
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
av.visitEnd()
AsmUtil.writeKotlinSyntheticClassAnnotation(v)
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
}
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.PackageContext;
import org.jetbrains.kotlin.codegen.context.RootContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAbi;
@@ -228,6 +229,13 @@ public class JvmCodegenUtil {
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, JvmAbi.VERSION.getMinor());
}
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
String name = state.getModuleName();
if (!name.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
av.visit(JvmAnnotationNames.MODULE_NAME_FIELD_NAME, name);
}
}
@NotNull
public static String sanitizeAsJavaIdentifier(@NotNull String str) {
return PackagePartClassUtils.sanitizeAsJavaIdentifier(str);
@@ -262,6 +262,7 @@ public class MultifileClassCodegen(
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
JvmCodegenUtil.writeAbiVersion(av)
JvmCodegenUtil.writeModuleName(av, state)
val partInternalNames = partFqNames.map { JvmClassName.byFqNameWithoutInnerClasses(it).internalName }.sorted()
val arv = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
@@ -43,6 +43,7 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackagePartCodegen extends MemberCodegen<JetFile> {
@@ -125,6 +126,7 @@ public class PackagePartCodegen extends MemberCodegen<JetFile> {
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
writeAnnotationData(av, serializer, packageProto);
writeModuleName(av, state);
av.visitEnd();
}
}
@@ -196,7 +196,7 @@ public class PropertyReferenceCodegen(
}
override fun generateKotlinAnnotation() {
writeKotlinSyntheticClassAnnotation(v)
writeKotlinSyntheticClassAnnotation(v, state)
}
public fun putInstanceOnStack(): StackValue =
@@ -93,7 +93,7 @@ public class SamWrapperCodegen {
);
cv.visitSource(file.getName(), null);
writeKotlinSyntheticClassAnnotation(cv);
writeKotlinSyntheticClassAnnotation(cv, state);
// e.g. ASM type for Function2
Type functionAsmType = typeMapper.mapType(functionType);
@@ -57,7 +57,7 @@ public class MappingClassesForWhenByEnumCodegen {
generateFields(cb, mappings);
generateInitialization(cb, mappings);
writeKotlinSyntheticClassAnnotation(cb);
writeKotlinSyntheticClassAnnotation(cb, state);
cb.done();
}
@@ -50,6 +50,7 @@ public final class JvmAnnotationNames {
public static final String MULTIFILE_CLASS_NAME_FIELD_NAME = "multifileClassName";
public static final String DATA_FIELD_NAME = "data";
public static final String STRINGS_FIELD_NAME = "strings";
public static final String MODULE_NAME_FIELD_NAME = "moduleName";
public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value");
public static final Name DEPRECATED_ANNOTATION_MESSAGE = Name.identifier("message");
public static final Name TARGET_ANNOTATION_MEMBER_NAME = Name.identifier("allowedTargets");
@@ -29,11 +29,9 @@ import kotlin.reflect.KPackage
internal class KPackageImpl(override val jClass: Class<*>, val moduleName: String) : KDeclarationContainerImpl(), KPackage {
val descriptor by ReflectProperties.lazySoft {
val moduleData = jClass.getOrCreateModule()
val moduleData = moduleData
moduleData.packageFacadeProvider.registerModule(moduleName)
val fqName = jClass.classId.getPackageFqName()
moduleData.module.getPackage(fqName)
moduleData.module.getPackage(jClass.classId.packageFqName)
}
internal val scope: JetScope get() = descriptor.memberScope
@@ -103,7 +103,13 @@ public val Method.kotlinFunction: KFunction<*>?
if (isSynthetic) return null
if (Modifier.isStatic(modifiers)) {
// TODO: support file facades & multifile classes
// TODO: support multifile classes
val fileFacade = declaringClass.getAnnotation(KotlinFileFacade::class.java)
if (fileFacade != null) {
val kotlinPackage = Reflection.getOrCreateKotlinPackage(declaringClass, fileFacade.moduleName)
return kotlinPackage.functions.firstOrNull { it.javaMethod == this }
}
// For static bridge method generated for a jvmStatic function in the companion object, also try to find the latter
val companion = declaringClass.kotlin.companionObject
@@ -29,6 +29,8 @@ public @interface KotlinCallable {
int[] version() default {};
String moduleName() default "main";
String[] data();
String[] strings();
@@ -29,6 +29,8 @@ public @interface KotlinClass {
int[] version() default {};
String moduleName() default "main";
String[] data();
String[] strings();
@@ -29,6 +29,8 @@ public @interface KotlinFileFacade {
int[] version() default {};
String moduleName() default "main";
String[] data();
String[] strings();
@@ -29,6 +29,8 @@ public @interface KotlinMultifileClass {
int[] version() default {};
String moduleName() default "main";
String[] filePartClassNames();
String[] strings();
@@ -28,4 +28,6 @@ public @interface KotlinSyntheticClass {
int abiVersion();
int[] version() default {};
String moduleName() default "main";
}