Jvm Codegen: do not throw on malformed delegation to a type parameter

Fix exception on light class building

See KT-15931
This commit is contained in:
Pavel V. Talanov
2017-06-05 14:58:50 +03:00
parent 19db4304bd
commit bdf76f23c4
4 changed files with 51 additions and 14 deletions
@@ -1105,9 +1105,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private final Map<KtDelegatedSuperTypeEntry, Field> fields = new HashMap<>();
@NotNull
@Nullable
public Field getInfo(KtDelegatedSuperTypeEntry specifier) {
return fields.get(specifier);
Field field = fields.get(specifier);
assert field != null || state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES : "No field for " + specifier.getText();
return field;
}
private void addField(KtDelegatedSuperTypeEntry specifier, PropertyDescriptor propertyDescriptor) {
@@ -1127,22 +1129,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
PropertyDescriptor propertyDescriptor = expression != null
? CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext)
: null;
if (expression == null) continue;
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
}
else {
KotlinType expressionType = expression != null
? bindingContext.getType(expression)
: null;
KotlinType expressionType = bindingContext.getType(expression);
ClassDescriptor superClass = getSuperClass(specifier);
if (superClass != null) {
Type asmType = expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(superClass);
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, JvmAbi.DELEGATE_SUPER_FIELD_PREFIX + n);
}
Type asmType =
expressionType != null ? typeMapper.mapType(expressionType) :
superClass != null ? typeMapper.mapType(superClass) : null;
if (asmType == null) continue;
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, JvmAbi.DELEGATE_SUPER_FIELD_PREFIX + n);
}
n++;
}
@@ -1152,7 +1156,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Nullable
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
ClassDescriptor superClass = CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
assert superClass != null || state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES
: "ClassDescriptor should not be null:" + specifier.getText();
return superClass;
}
private void genCallToDelegatorByExpressionSpecifier(
@@ -1164,6 +1172,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
KtExpression expression = specifier.getDelegateExpression();
DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier);
if (fieldInfo == null) return;
if (fieldInfo.generateField) {
iv.load(0, classAsmType);
fieldInfo.getStackValue().store(codegen.gen(expression), iv);
@@ -1609,10 +1619,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatedSuperTypeEntry) specifier);
if (field == null) continue;
generateDelegateField(field);
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
KotlinType delegateExpressionType = delegateExpression != null ? bindingContext.getType(delegateExpression) : null;
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
ClassDescriptor superClass = getSuperClass(specifier);
if (superClass == null) continue;
generateDelegates(superClass, delegateExpressionType, field);
}
}
}