From 64d1d3eda6655beb8b4b0db1ee739fdb64e3e997 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 8 Jun 2012 21:49:31 +0400 Subject: [PATCH] KT-2193 Nullability information lost for functions inherited from traits #KT-2193 fixed --- .../codegen/ImplementationBodyCodegen.java | 27 ++++++++++++++++--- .../classFun/FunDelegationToTraitImpl.kt | 9 +++++++ .../classFun/FunDelegationToTraitImpl.txt | 9 +++++++ .../prop/VarDelegationToTraitImpl.kt | 13 +++++++++ .../prop/VarDelegationToTraitImpl.txt | 9 +++++++ 5 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.kt create mode 100644 compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.txt create mode 100644 compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.kt create mode 100644 compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.txt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index cec73ebd275..d7431e8ff05 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -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 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 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); } diff --git a/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.kt b/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.kt new file mode 100644 index 00000000000..4b0dcb7b986 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.kt @@ -0,0 +1,9 @@ +package test + +// test composed from KT-2193 + +trait A { + open fun f(): String = "test" +} + +class B() : A \ No newline at end of file diff --git a/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.txt b/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.txt new file mode 100644 index 00000000000..38249f2f6c7 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/classFun/FunDelegationToTraitImpl.txt @@ -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 (): test.B + open override /*1*/ fun f(): jet.String +} diff --git a/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.kt b/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.kt new file mode 100644 index 00000000000..819754f5272 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.kt @@ -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 \ No newline at end of file diff --git a/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.txt b/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.txt new file mode 100644 index 00000000000..b342f5730d3 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/prop/VarDelegationToTraitImpl.txt @@ -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 (): test.B + open var v: jet.String +}