Move generation of non-local interface DefaultImpls

`DefaultImpls` should be inner class of it's interface,
so for proper light classes building it should be built
before original interface has been done, i.e. `done` method called.

Everything is complicated with local interfaces, so they are just left untouched
This commit is contained in:
Denis Zharkov
2015-09-28 11:06:21 +03:00
parent a101fffd9a
commit c1bed7efc7
3 changed files with 24 additions and 12 deletions
@@ -211,8 +211,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION);
MemberCodegen literalCodegen = new ImplementationBodyCodegen(
objectDeclaration, objectContext, classBuilder, state, getParentCodegen()
);
objectDeclaration, objectContext, classBuilder, state, getParentCodegen(),
/* isLocal = */ true);
literalCodegen.generate();
addReifiedParametersFromSignature(literalCodegen, classDescriptor);
@@ -330,7 +330,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ClassBuilder classBuilder = state.getFactory().newVisitor(OtherOrigin(declaration, descriptor), asmType, declaration.getContainingFile());
ClassContext objectContext = context.intoAnonymousClass(descriptor, this, OwnerKind.IMPLEMENTATION);
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen()).generate();
new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, getParentCodegen(), /* isLocal = */ true).generate();
if (declaration instanceof JetClass && ((JetClass) declaration).isInterface()) {
Type traitImplType = state.getTypeMapper().mapDefaultImpls(descriptor);
@@ -100,6 +100,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Nullable // null means java/lang/Object
private JetType superClassType;
private final Type classAsmType;
private final boolean isLocal;
private List<PropertyAndDefaultValue> companionObjectPropertiesToCopy;
@@ -111,10 +112,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@NotNull ClassContext context,
@NotNull ClassBuilder v,
@NotNull GenerationState state,
@Nullable MemberCodegen<?> parentCodegen
@Nullable MemberCodegen<?> parentCodegen,
boolean isLocal
) {
super(aClass, context, v, state, parentCodegen);
this.classAsmType = typeMapper.mapClass(descriptor);
this.isLocal = isLocal;
}
@Override
@@ -231,6 +234,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateEnumEntries();
}
@Override
protected void generateBody() {
super.generateBody();
if (isInterface(descriptor) && !isLocal) {
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
ClassBuilder defaultImplsBuilder =
state.getFactory().newVisitor(TraitImpl(myClass, descriptor), defaultImplsType, myClass.getContainingFile());
CodegenContext parentContext = context.getParentContext();
assert parentContext != null : "Parent context of interface declaration should not be null";
ClassContext defaultImplsContext = parentContext.intoClass(descriptor, OwnerKind.DEFAULT_IMPLS, state);
new InterfaceImplBodyCodegen(myClass, defaultImplsContext, defaultImplsBuilder, state, this).generate();
}
}
@Override
protected void generateKotlinAnnotation() {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
@@ -205,14 +205,7 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
Type classType = state.getTypeMapper().mapClass(descriptor);
ClassBuilder classBuilder = state.getFactory().newVisitor(OtherOrigin(aClass, descriptor), classType, aClass.getContainingFile());
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen).generate();
if (aClass instanceof JetClass && ((JetClass) aClass).isInterface()) {
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
ClassBuilder defaultImplsBuilder = state.getFactory().newVisitor(TraitImpl(aClass, descriptor), defaultImplsType, aClass.getContainingFile());
ClassContext defaultImplsContext = parentContext.intoClass(descriptor, OwnerKind.DEFAULT_IMPLS, state);
new InterfaceImplBodyCodegen(aClass, defaultImplsContext, defaultImplsBuilder, state, parentCodegen).generate();
}
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen, false).generate();
}
private static void badDescriptor(ClassDescriptor descriptor, ClassBuilderMode mode) {