Handle incorrect code for interface delegation

#KT-15931 Fixed Target versions 1.1.4
This commit is contained in:
Dmitry Petrov
2017-05-29 12:17:00 +03:00
parent 4f132f6d40
commit 78de1fb72c
3 changed files with 17 additions and 11 deletions
@@ -101,12 +101,11 @@ object CodegenUtil {
} }
@JvmStatic @JvmStatic
fun getSuperClassBySuperTypeListEntry(specifier: KtSuperTypeListEntry, bindingContext: BindingContext): ClassDescriptor { fun getSuperClassBySuperTypeListEntry(specifier: KtSuperTypeListEntry, bindingContext: BindingContext): ClassDescriptor? {
val superType = bindingContext.get(BindingContext.TYPE, specifier.typeReference!!) val superType = bindingContext.get(BindingContext.TYPE, specifier.typeReference!!)
?: error("superType should not be null: ${specifier.text}") ?: error("superType should not be null: ${specifier.text}")
return superType.constructor.declarationDescriptor as? ClassDescriptor return superType.constructor.declarationDescriptor as? ClassDescriptor
?: error("ClassDescriptor of superType should not be null: ${specifier.text}")
} }
@JvmStatic @JvmStatic
@@ -1127,17 +1127,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtSuperTypeListEntry specifier : delegationSpecifiers) { for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
if (specifier instanceof KtDelegatedSuperTypeEntry) { if (specifier instanceof KtDelegatedSuperTypeEntry) {
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression(); KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext); PropertyDescriptor propertyDescriptor = expression != null
? CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext)
: null;
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) { if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor); result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
} }
else { else {
KotlinType expressionType = expression != null ? bindingContext.getType(expression) : null; KotlinType expressionType = expression != null
Type asmType = ? bindingContext.getType(expression)
expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(getSuperClass(specifier)); : null;
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, JvmAbi.DELEGATE_SUPER_FIELD_PREFIX + n); 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);
}
} }
n++; n++;
} }
@@ -1145,7 +1150,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
return result; return result;
} }
@NotNull @Nullable
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) { private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext); return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
} }
@@ -86,11 +86,13 @@ class DelegationTranslator(
fun generateDelegated() { fun generateDelegated() {
for (specifier in delegationBySpecifiers) { for (specifier in delegationBySpecifiers) {
generateDelegates(specifier, getSuperClass(specifier), fields[specifier]!!) getSuperClass(specifier)?.let {
generateDelegates(specifier, it, fields[specifier]!!)
}
} }
} }
private fun getSuperClass(specifier: KtSuperTypeListEntry): ClassDescriptor = private fun getSuperClass(specifier: KtSuperTypeListEntry): ClassDescriptor? =
CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext()) CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext())
private fun generateDelegates(specifier: KtSuperTypeListEntry, toClass: ClassDescriptor, field: Field) { private fun generateDelegates(specifier: KtSuperTypeListEntry, toClass: ClassDescriptor, field: Field) {