From 5af90c2a8392d379b6466119655beadfca1ff947 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 19 Sep 2012 19:03:23 +0400 Subject: [PATCH] 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. --- .../codegen/ImplementationBodyCodegen.java | 54 +++++++++++-------- .../jet/lang/resolve/DescriptorUtils.java | 10 ++++ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 050ae292c91..1a71ee20bac 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -41,6 +41,7 @@ import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; 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.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; @@ -165,42 +166,29 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ); v.visitSource(myClass.getContainingFile().getName(), null); - writeInnerOuterClasses(); + writeOuterClass(); + + writeInnerClasses(); AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor); writeClassSignatureIfNeeded(signature); } - private void writeInnerOuterClasses() { + private void writeOuterClass() { ClassDescriptor container = getContainingClassDescriptor(descriptor); if (container != null) { v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName(), null, null); } + } - for (DeclarationDescriptor declarationDescriptor : descriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) { - assert declarationDescriptor instanceof ClassDescriptor; - ClassDescriptor innerClass = (ClassDescriptor) declarationDescriptor; - // 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); + private void writeInnerClasses() { + for (ClassDescriptor innerClass : DescriptorUtils.getInnerClasses(descriptor)) { + writeInnerClass(innerClass); } - if (descriptor.getClassObjectDescriptor() != null) { + ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); + if (classObjectDescriptor != null) { int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC; v.visitInnerClass(classAsmType.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX, classAsmType.getInternalName(), 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) { if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) { AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 2413cd5bd85..990ab991d7d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -355,4 +355,14 @@ public class DescriptorUtils { + (classifier == null ? "null" : classifier.getClass()); return (ClassDescriptor) classifier; } + + @SuppressWarnings("unchecked") + public static Collection getInnerClasses(ClassDescriptor classDescriptor) { + Collection 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; + } }