Inner class generation now performed on visiting appropriate declaration
This commit is contained in:
@@ -34,6 +34,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||||
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
|
|
||||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||||
protected final JetClassOrObject myClass;
|
protected final JetClassOrObject myClass;
|
||||||
@@ -85,6 +86,17 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
||||||
genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v);
|
genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v);
|
||||||
}
|
}
|
||||||
|
else if (declaration instanceof JetClassOrObject) {
|
||||||
|
if (declaration instanceof JetEnumEntry && !enumEntryNeedSubclass(
|
||||||
|
state.getBindingContext(), (JetEnumEntry) declaration)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
genClassOrObject(context, (JetClassOrObject) declaration);
|
||||||
|
}
|
||||||
|
else if (declaration instanceof JetClassObject) {
|
||||||
|
genClassOrObject(context, ((JetClassObject) declaration).getObjectDeclaration());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) {
|
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) {
|
||||||
|
|||||||
@@ -121,15 +121,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
//noinspection SuspiciousMethodCalls
|
//noinspection SuspiciousMethodCalls
|
||||||
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
||||||
|
|
||||||
CodegenContext contextForInners = context.intoClass(classDescriptor, OwnerKind.IMPLEMENTATION, state);
|
|
||||||
|
|
||||||
CodegenContext objectContext = context.intoAnonymousClass(classDescriptor, this);
|
CodegenContext objectContext = context.intoAnonymousClass(classDescriptor, this);
|
||||||
ImplementationBodyCodegen implementationBodyCodegen = new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state);
|
ImplementationBodyCodegen implementationBodyCodegen = new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state);
|
||||||
|
|
||||||
implementationBodyCodegen.genInners(contextForInners, state, objectDeclaration);
|
|
||||||
|
|
||||||
objectContext.copyAccessors(contextForInners.getAccessors());
|
|
||||||
|
|
||||||
implementationBodyCodegen.generate();
|
implementationBodyCodegen.generate();
|
||||||
|
|
||||||
return closure;
|
return closure;
|
||||||
|
|||||||
@@ -1508,10 +1508,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
||||||
if (declaration instanceof JetClassObject || declaration instanceof JetObjectDeclaration) {
|
if (declaration instanceof JetEnumEntry) {
|
||||||
// done earlier in order to have accessors
|
|
||||||
}
|
|
||||||
else if (declaration instanceof JetEnumEntry) {
|
|
||||||
String name = declaration.getName();
|
String name = declaration.getName();
|
||||||
String desc = "L" + classAsmType.getInternalName() + ";";
|
String desc = "L" + classAsmType.getInternalName() + ";";
|
||||||
v.newField(declaration, ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL, name, desc, null, null);
|
v.newField(declaration, ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL, name, desc, null, null);
|
||||||
@@ -1525,9 +1522,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
myEnumConstants.add((JetEnumEntry) declaration);
|
myEnumConstants.add((JetEnumEntry) declaration);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
super.generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
super.generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
|
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
|
||||||
|
|||||||
@@ -68,48 +68,7 @@ public class MemberCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genImplementation(
|
public void genClassOrObject(CodegenContext parentContext, JetClassOrObject aClass) {
|
||||||
CodegenContext context,
|
|
||||||
GenerationState state,
|
|
||||||
JetClassOrObject aClass,
|
|
||||||
OwnerKind kind,
|
|
||||||
Map<DeclarationDescriptor, DeclarationDescriptor> accessors,
|
|
||||||
ClassBuilder classBuilder
|
|
||||||
) {
|
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
|
||||||
CodegenContext classContext = context.intoClass(descriptor, kind, state);
|
|
||||||
classContext.copyAccessors(accessors);
|
|
||||||
|
|
||||||
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate();
|
|
||||||
|
|
||||||
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
|
||||||
ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile());
|
|
||||||
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state)
|
|
||||||
.generate();
|
|
||||||
traitBuilder.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void genInners(CodegenContext context, GenerationState state, JetClassOrObject aClass) {
|
|
||||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
|
||||||
if (declaration instanceof JetClass) {
|
|
||||||
if (declaration instanceof JetEnumEntry && !enumEntryNeedSubclass(
|
|
||||||
state.getBindingContext(), (JetEnumEntry) declaration)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
genClassOrObject(context, (JetClass) declaration);
|
|
||||||
}
|
|
||||||
else if (declaration instanceof JetClassObject) {
|
|
||||||
genClassOrObject(context, ((JetClassObject) declaration).getObjectDeclaration());
|
|
||||||
}
|
|
||||||
else if (declaration instanceof JetObjectDeclaration) {
|
|
||||||
genClassOrObject(context, (JetObjectDeclaration) declaration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void genClassOrObject(CodegenContext context, JetClassOrObject aClass) {
|
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
|
|
||||||
if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(JetPsiUtil.NO_NAME_PROVIDED)) {
|
if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(JetPsiUtil.NO_NAME_PROVIDED)) {
|
||||||
@@ -121,22 +80,15 @@ public class MemberCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile());
|
||||||
|
CodegenContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
||||||
CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
|
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate();
|
||||||
|
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) {
|
|
||||||
// Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate
|
|
||||||
// The same code is present below for the case when we genClassOrObject real bytecode. This is because the order should be
|
|
||||||
// different for the case when we compute closures
|
|
||||||
genImplementation(context, state, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
genInners(contextForInners, state, aClass);
|
|
||||||
|
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
|
||||||
genImplementation(context, state, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
classBuilder.done();
|
classBuilder.done();
|
||||||
|
|
||||||
|
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
||||||
|
ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state, aClass.getContainingFile());
|
||||||
|
new TraitImplBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state)
|
||||||
|
.generate();
|
||||||
|
traitBuilder.done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user