Do not skip delegated members in LIGHT_CLASSES mode
This commit is contained in:
@@ -49,6 +49,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmClassSignature;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmClassSignature;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
|
||||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
|
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
|
||||||
@@ -434,8 +435,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
generateClassObjectBackingFieldCopies();
|
generateClassObjectBackingFieldCopies();
|
||||||
|
|
||||||
|
DelegationFieldsInfo delegationFieldsInfo = getDelegationFieldsInfo(myClass.getDelegationSpecifiers());
|
||||||
try {
|
try {
|
||||||
generatePrimaryConstructor();
|
generatePrimaryConstructor(delegationFieldsInfo);
|
||||||
}
|
}
|
||||||
catch (CompilationException e) {
|
catch (CompilationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
@@ -449,6 +451,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
generateTraitMethods();
|
generateTraitMethods();
|
||||||
|
|
||||||
|
generateDelegates(delegationFieldsInfo);
|
||||||
|
|
||||||
generateSyntheticAccessors();
|
generateSyntheticAccessors();
|
||||||
|
|
||||||
generateEnumMethodsAndConstInitializers();
|
generateEnumMethodsAndConstInitializers();
|
||||||
@@ -1123,7 +1127,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generatePrimaryConstructor() {
|
protected void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
|
||||||
if (ignoreIfTraitOrAnnotation()) return;
|
if (ignoreIfTraitOrAnnotation()) return;
|
||||||
|
|
||||||
if (kind != OwnerKind.IMPLEMENTATION) {
|
if (kind != OwnerKind.IMPLEMENTATION) {
|
||||||
@@ -1152,7 +1156,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
generatePrimaryConstructorImpl(callableDescriptor, codegen, closure);
|
generatePrimaryConstructorImpl(callableDescriptor, codegen, closure, delegationFieldsInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1171,7 +1175,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private void generatePrimaryConstructorImpl(
|
private void generatePrimaryConstructorImpl(
|
||||||
@Nullable ConstructorDescriptor constructorDescriptor,
|
@Nullable ConstructorDescriptor constructorDescriptor,
|
||||||
@NotNull final ExpressionCodegen codegen,
|
@NotNull final ExpressionCodegen codegen,
|
||||||
@Nullable MutableClosure closure
|
@Nullable MutableClosure closure,
|
||||||
|
@NotNull DelegationFieldsInfo fieldsInfo
|
||||||
) {
|
) {
|
||||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||||
? constructorDescriptor.getValueParameters()
|
? constructorDescriptor.getValueParameters()
|
||||||
@@ -1197,14 +1202,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor);
|
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||||
if (specifier == superCall) {
|
if (specifier == superCall) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
genCallToDelegatorByExpressionSpecifier(iv, codegen, n++, specifier);
|
genCallToDelegatorByExpressionSpecifier(iv, codegen, (JetDelegatorByExpressionSpecifier) specifier, fieldsInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,13 +1279,95 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DelegationFieldsInfo {
|
||||||
|
private class Field {
|
||||||
|
public final Type type;
|
||||||
|
public final String name;
|
||||||
|
public final boolean generateField;
|
||||||
|
|
||||||
|
private Field(Type type, String name, boolean generateField) {
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
this.generateField = generateField;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public StackValue getStackValue() {
|
||||||
|
return StackValue.field(type, classAsmType, name, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private final Map<JetDelegatorByExpressionSpecifier, Field> fields = new HashMap<JetDelegatorByExpressionSpecifier, Field>();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Field getInfo(JetDelegatorByExpressionSpecifier specifier) {
|
||||||
|
return fields.get(specifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addField(JetDelegatorByExpressionSpecifier specifier, PropertyDescriptor propertyDescriptor) {
|
||||||
|
fields.put(specifier,
|
||||||
|
new Field(typeMapper.mapType(propertyDescriptor), propertyDescriptor.getName().asString(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addField(JetDelegatorByExpressionSpecifier specifier, Type type, String name) {
|
||||||
|
fields.put(specifier, new Field(type, name, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<JetDelegationSpecifier> delegationSpecifiers) {
|
||||||
|
DelegationFieldsInfo result = new DelegationFieldsInfo();
|
||||||
|
int n = 0;
|
||||||
|
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||||
|
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
|
JetExpression expression = ((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||||
|
PropertyDescriptor propertyDescriptor = getDelegatePropertyIfAny(expression);
|
||||||
|
|
||||||
|
ClassDescriptor superClassDescriptor = getSuperClass(specifier);
|
||||||
|
|
||||||
|
if (propertyDescriptor != null &&
|
||||||
|
!propertyDescriptor.isVar() &&
|
||||||
|
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor))) {
|
||||||
|
// final property with backing field
|
||||||
|
result.addField((JetDelegatorByExpressionSpecifier) specifier, propertyDescriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.addField((JetDelegatorByExpressionSpecifier) specifier, typeMapper.mapType(superClassDescriptor), "$delegate_" + n);
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private ClassDescriptor getSuperClass(@NotNull JetDelegationSpecifier specifier) {
|
||||||
|
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
|
assert superType != null;
|
||||||
|
|
||||||
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
|
assert superClassDescriptor != null;
|
||||||
|
return superClassDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
private void genCallToDelegatorByExpressionSpecifier(
|
private void genCallToDelegatorByExpressionSpecifier(
|
||||||
InstructionAdapter iv,
|
InstructionAdapter iv,
|
||||||
ExpressionCodegen codegen,
|
ExpressionCodegen codegen,
|
||||||
int n,
|
JetDelegatorByExpressionSpecifier specifier,
|
||||||
JetDelegationSpecifier specifier
|
DelegationFieldsInfo fieldsInfo
|
||||||
) {
|
) {
|
||||||
JetExpression expression = ((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
JetExpression expression = specifier.getDelegateExpression();
|
||||||
|
|
||||||
|
DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier);
|
||||||
|
if (fieldInfo.generateField) {
|
||||||
|
iv.load(0, classAsmType);
|
||||||
|
codegen.genToJVMStack(expression);
|
||||||
|
|
||||||
|
fieldInfo.getStackValue().store(fieldInfo.type, iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private PropertyDescriptor getDelegatePropertyIfAny(JetExpression expression) {
|
||||||
PropertyDescriptor propertyDescriptor = null;
|
PropertyDescriptor propertyDescriptor = null;
|
||||||
if (expression instanceof JetSimpleNameExpression) {
|
if (expression instanceof JetSimpleNameExpression) {
|
||||||
ResolvedCall<?> call = bindingContext.get(BindingContext.RESOLVED_CALL, expression);
|
ResolvedCall<?> call = bindingContext.get(BindingContext.RESOLVED_CALL, expression);
|
||||||
@@ -1301,35 +1387,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
// todo: when and if frontend will allow properties defined not as constructor parameters to be used in delegation specifier
|
// todo: when and if frontend will allow properties defined not as constructor parameters to be used in delegation specifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return propertyDescriptor;
|
||||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
|
||||||
assert superType != null;
|
|
||||||
|
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
|
||||||
assert superClassDescriptor != null;
|
|
||||||
|
|
||||||
StackValue field;
|
|
||||||
if (propertyDescriptor != null &&
|
|
||||||
!propertyDescriptor.isVar() &&
|
|
||||||
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor))) {
|
|
||||||
// final property with backing field
|
|
||||||
field = StackValue.field(typeMapper.mapType(propertyDescriptor), classAsmType, propertyDescriptor.getName().asString(), false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iv.load(0, classAsmType);
|
|
||||||
codegen.genToJVMStack(expression);
|
|
||||||
|
|
||||||
String delegateField = "$delegate_" + n;
|
|
||||||
Type fieldType = typeMapper.mapType(superClassDescriptor);
|
|
||||||
String fieldDesc = fieldType.getDescriptor();
|
|
||||||
|
|
||||||
v.newField(OtherOrigin(specifier), ACC_PRIVATE | ACC_FINAL | ACC_SYNTHETIC, delegateField, fieldDesc, /*TODO*/null, null);
|
|
||||||
|
|
||||||
field = StackValue.field(fieldType, classAsmType, delegateField, false);
|
|
||||||
field.store(fieldType, iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
generateDelegates(superClassDescriptor, field);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void lookupConstructorExpressionsInClosureIfPresent(final ConstructorContext constructorContext) {
|
private void lookupConstructorExpressionsInClosureIfPresent(final ConstructorContext constructorContext) {
|
||||||
@@ -1625,7 +1683,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.astore(OBJECT_TYPE);
|
iv.astore(OBJECT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDelegates(ClassDescriptor toClass, StackValue field) {
|
private void generateDelegates(DelegationFieldsInfo delegationFieldsInfo) {
|
||||||
|
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||||
|
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
|
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((JetDelegatorByExpressionSpecifier) specifier);
|
||||||
|
generateDelegateField(field);
|
||||||
|
generateDelegates(getSuperClass(specifier), field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateDelegateField(DelegationFieldsInfo.Field fieldInfo) {
|
||||||
|
if (!fieldInfo.generateField) return;
|
||||||
|
|
||||||
|
v.newField(JvmDeclarationOrigin.NO_ORIGIN, ACC_PRIVATE | ACC_FINAL | ACC_SYNTHETIC,
|
||||||
|
fieldInfo.name, fieldInfo.type.getDescriptor(), /*TODO*/null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void generateDelegates(ClassDescriptor toClass, DelegationFieldsInfo.Field field) {
|
||||||
for (DeclarationDescriptor declaration : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
for (DeclarationDescriptor declaration : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||||
if (declaration instanceof CallableMemberDescriptor) {
|
if (declaration instanceof CallableMemberDescriptor) {
|
||||||
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) declaration;
|
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) declaration;
|
||||||
@@ -1635,11 +1710,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (overriddenDescriptor.getContainingDeclaration() == toClass) {
|
if (overriddenDescriptor.getContainingDeclaration() == toClass) {
|
||||||
if (declaration instanceof PropertyDescriptor) {
|
if (declaration instanceof PropertyDescriptor) {
|
||||||
propertyCodegen
|
propertyCodegen
|
||||||
.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field);
|
.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field.getStackValue());
|
||||||
}
|
}
|
||||||
else if (declaration instanceof FunctionDescriptor) {
|
else if (declaration instanceof FunctionDescriptor) {
|
||||||
functionCodegen
|
functionCodegen
|
||||||
.genDelegate((FunctionDescriptor) declaration, (FunctionDescriptor) overriddenDescriptor, field);
|
.genDelegate((FunctionDescriptor) declaration, (FunctionDescriptor) overriddenDescriptor, field.getStackValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -CONFLICTING_JVM_DECLARATIONS
|
||||||
trait One {
|
trait One {
|
||||||
public fun foo(): Any?
|
public fun foo(): Any?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// !DIAGNOSTICS: -CONFLICTING_JVM_DECLARATIONS
|
||||||
trait One {
|
trait One {
|
||||||
public open fun foo() : Int
|
public open fun foo() : Int
|
||||||
private fun boo() = 10
|
private fun boo() = 10
|
||||||
@@ -15,4 +16,4 @@ trait TwoImpl : Two {
|
|||||||
|
|
||||||
class <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>Test1<!>() : TwoImpl, OneImpl {}
|
class <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>Test1<!>() : TwoImpl, OneImpl {}
|
||||||
class Test2(a : One) : One by a, Two {}
|
class Test2(a : One) : One by a, Two {}
|
||||||
class <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>Test3<!>(a : One, b : Two) : Two by b, One by a {}
|
class <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>Test3<!>(a : One, b : Two) : Two by b, One by a {}
|
||||||
+1
-1
@@ -6,5 +6,5 @@ trait D {
|
|||||||
val x: Int
|
val x: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class <!ACCIDENTAL_OVERRIDE!>C(d: D)<!> : D by d, B {
|
class <!CONFLICTING_JVM_DECLARATIONS!>C(d: D)<!> : D by d, B {
|
||||||
}
|
}
|
||||||
+1
-1
@@ -8,5 +8,5 @@ trait Bar<T> {
|
|||||||
fun foo(l: List<T>)
|
fun foo(l: List<T>)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!CONFLICTING_JVM_DECLARATIONS!>class Baz(f: Foo<String>, b: Bar<Int>)<!>: Foo<String> by f, Bar<Int> by b {
|
class <!CONFLICTING_JVM_DECLARATIONS!>Baz(f: Foo<String>, b: Bar<Int>)<!>: Foo<String> by f, Bar<Int> by b {
|
||||||
}
|
}
|
||||||
+1
-1
@@ -4,6 +4,6 @@ trait Foo<T> {
|
|||||||
fun foo(l: List<T>)
|
fun foo(l: List<T>)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar(f: Foo<String>): Foo<String> by f {
|
class <!CONFLICTING_JVM_DECLARATIONS!>Bar(f: Foo<String>)<!>: Foo<String> by f {
|
||||||
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(l: List<Int>)<!> {}
|
<!CONFLICTING_JVM_DECLARATIONS!>fun foo(l: List<Int>)<!> {}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
trait Foo
|
trait Foo
|
||||||
|
|
||||||
class Bar(f: Foo) : Foo by f {
|
class <!CONFLICTING_JVM_DECLARATIONS!>Bar(f: Foo)<!> : Foo by f {
|
||||||
<!CONFLICTING_JVM_DECLARATIONS!>val `$delegate_0`: Foo?<!> = null
|
<!CONFLICTING_JVM_DECLARATIONS!>val `$delegate_0`: Foo?<!> = null
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user