KT-2193 Nullability information lost for functions inherited from traits

#KT-2193 fixed
This commit is contained in:
Evgeny Gerashchenko
2012-06-08 21:49:31 +04:00
parent 208dd4e35d
commit 64d1d3eda6
5 changed files with 64 additions and 3 deletions
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.signature.*;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
@@ -720,18 +721,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
CallableMemberDescriptor callableDescriptor = needDelegates.first;
if (needDelegates.second instanceof SimpleFunctionDescriptor) {
generateDelegationToTraitImpl(codegen, (FunctionDescriptor) needDelegates.second);
generateDelegationToTraitImpl(codegen, (FunctionDescriptor) needDelegates.second, (FunctionDescriptor) needDelegates.first);
}
else if (needDelegates.second instanceof PropertyDescriptor) {
PropertyDescriptor property = (PropertyDescriptor) needDelegates.second;
List<PropertyAccessorDescriptor> inheritedAccessors = ((PropertyDescriptor) needDelegates.first).getAccessors();
for (PropertyAccessorDescriptor accessor : property.getAccessors()) {
generateDelegationToTraitImpl(codegen, accessor);
for (PropertyAccessorDescriptor inheritedAccessor : inheritedAccessors) {
if (inheritedAccessor.getClass() == accessor.getClass()) { // same accessor kind
generateDelegationToTraitImpl(codegen, accessor, inheritedAccessor);
}
}
}
}
}
}
private void generateDelegationToTraitImpl(ExpressionCodegen codegen, FunctionDescriptor fun) {
private void generateDelegationToTraitImpl(ExpressionCodegen codegen, FunctionDescriptor fun, @NotNull FunctionDescriptor inheritedFun) {
DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration();
if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor declaration = (ClassDescriptor) containingDeclaration;
@@ -745,6 +752,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal()).getAsmMethod();
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun);
JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature();
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
if (fun instanceof PropertyAccessorDescriptor) {
aw.writeFlags(JvmStdlibNames.JET_METHOD_FLAG_PROPERTY_BIT);
} else {
aw.writeFlags();
}
aw.writeNullableReturnType(fun.getReturnType().isNullable());
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
aw.writeReturnType(jvmSignature.getKotlinReturnType());
aw.visitEnd();
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv);
}
@@ -0,0 +1,9 @@
package test
// test composed from KT-2193
trait A {
open fun f(): String = "test"
}
class B() : A
@@ -0,0 +1,9 @@
namespace test
abstract trait test.A : jet.Any {
open fun f(): jet.String
}
final class test.B : test.A {
final /*constructor*/ fun <init>(): test.B
open override /*1*/ fun f(): jet.String
}
@@ -0,0 +1,13 @@
package test
// test composed from KT-2193
trait A {
open var v: String
get() = "test"
set(value) {
throw UnsupportedOperationException()
}
}
class B() : A
@@ -0,0 +1,9 @@
namespace test
abstract trait test.A : jet.Any {
open var v: jet.String
}
final class test.B : test.A {
final /*constructor*/ fun <init>(): test.B
open var v: jet.String
}