Extract some methods in codegen
Introduce DescriptorUtils#getInnerClasses(), which gets all descriptors from inner classes scope and asserts that they are classes. Inner/outer classes attributes are generated in separate methods.
This commit is contained in:
@@ -41,6 +41,7 @@ import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
@@ -165,42 +166,29 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
);
|
);
|
||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||||
|
|
||||||
writeInnerOuterClasses();
|
writeOuterClass();
|
||||||
|
|
||||||
|
writeInnerClasses();
|
||||||
|
|
||||||
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
|
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
|
||||||
|
|
||||||
writeClassSignatureIfNeeded(signature);
|
writeClassSignatureIfNeeded(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeInnerOuterClasses() {
|
private void writeOuterClass() {
|
||||||
ClassDescriptor container = getContainingClassDescriptor(descriptor);
|
ClassDescriptor container = getContainingClassDescriptor(descriptor);
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName(), null, null);
|
v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName(), null, null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (DeclarationDescriptor declarationDescriptor : descriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
|
private void writeInnerClasses() {
|
||||||
assert declarationDescriptor instanceof ClassDescriptor;
|
for (ClassDescriptor innerClass : DescriptorUtils.getInnerClasses(descriptor)) {
|
||||||
ClassDescriptor innerClass = (ClassDescriptor) declarationDescriptor;
|
writeInnerClass(innerClass);
|
||||||
// TODO: proper access
|
|
||||||
int innerClassAccess = ACC_PUBLIC;
|
|
||||||
if (innerClass.getModality() == Modality.FINAL) {
|
|
||||||
innerClassAccess |= ACC_FINAL;
|
|
||||||
}
|
|
||||||
else if (innerClass.getModality() == Modality.ABSTRACT) {
|
|
||||||
innerClassAccess |= ACC_ABSTRACT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (innerClass.getKind() == ClassKind.TRAIT) {
|
|
||||||
innerClassAccess |= ACC_INTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: cache internal names
|
|
||||||
String outerClassInernalName = classAsmType.getInternalName();
|
|
||||||
String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName();
|
|
||||||
v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName().getName(), innerClassAccess);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor.getClassObjectDescriptor() != null) {
|
ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor();
|
||||||
|
if (classObjectDescriptor != null) {
|
||||||
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
||||||
v.visitInnerClass(classAsmType.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX, classAsmType.getInternalName(),
|
v.visitInnerClass(classAsmType.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX, classAsmType.getInternalName(),
|
||||||
JvmAbi.CLASS_OBJECT_CLASS_NAME,
|
JvmAbi.CLASS_OBJECT_CLASS_NAME,
|
||||||
@@ -208,6 +196,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeInnerClass(ClassDescriptor innerClass) {
|
||||||
|
// TODO: proper access
|
||||||
|
int innerClassAccess = ACC_PUBLIC;
|
||||||
|
if (innerClass.getModality() == Modality.FINAL) {
|
||||||
|
innerClassAccess |= ACC_FINAL;
|
||||||
|
}
|
||||||
|
else if (innerClass.getModality() == Modality.ABSTRACT) {
|
||||||
|
innerClassAccess |= ACC_ABSTRACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (innerClass.getKind() == ClassKind.TRAIT) {
|
||||||
|
innerClassAccess |= ACC_INTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: cache internal names
|
||||||
|
String outerClassInternalName = classAsmType.getInternalName();
|
||||||
|
String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName();
|
||||||
|
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerClass.getName().getName(), innerClassAccess);
|
||||||
|
}
|
||||||
|
|
||||||
private void writeClassSignatureIfNeeded(JvmClassSignature signature) {
|
private void writeClassSignatureIfNeeded(JvmClassSignature signature) {
|
||||||
if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) {
|
if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) {
|
||||||
AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true);
|
AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true);
|
||||||
|
|||||||
@@ -355,4 +355,14 @@ public class DescriptorUtils {
|
|||||||
+ (classifier == null ? "null" : classifier.getClass());
|
+ (classifier == null ? "null" : classifier.getClass());
|
||||||
return (ClassDescriptor) classifier;
|
return (ClassDescriptor) classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Collection<ClassDescriptor> getInnerClasses(ClassDescriptor classDescriptor) {
|
||||||
|
Collection<DeclarationDescriptor> innerClasses = classDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors();
|
||||||
|
for (DeclarationDescriptor inner : innerClasses) {
|
||||||
|
assert inner instanceof ClassDescriptor
|
||||||
|
: "Not a class in inner classes scope of " + classDescriptor + ": " + inner;
|
||||||
|
}
|
||||||
|
return (Collection) innerClasses;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user