KT-2228 Open and final trait members are loaded as abstract from binary Kotlin classes.
Added storing modality for trait members in @JetMethod annotations. #KT-2228 Fixed
This commit is contained in:
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.objectweb.asm.Label;
|
||||
@@ -97,8 +98,9 @@ public class FunctionCodegen {
|
||||
{
|
||||
flags |= ACC_VARARGS;
|
||||
}
|
||||
|
||||
if (functionDescriptor.getModality() == Modality.FINAL) {
|
||||
|
||||
Modality modality = functionDescriptor.getModality();
|
||||
if (modality == Modality.FINAL) {
|
||||
flags |= ACC_FINAL;
|
||||
}
|
||||
|
||||
@@ -117,7 +119,7 @@ public class FunctionCodegen {
|
||||
flags |= ACC_STATIC;
|
||||
|
||||
boolean isAbstract = (
|
||||
functionDescriptor.getModality() == Modality.ABSTRACT
|
||||
modality == Modality.ABSTRACT
|
||||
|| CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())
|
||||
) && !isStatic && kind != OwnerKind.TRAIT_IMPL;
|
||||
if (isAbstract) flags |= ACC_ABSTRACT;
|
||||
@@ -128,14 +130,23 @@ public class FunctionCodegen {
|
||||
int start = 0;
|
||||
if (needJetAnnotations) {
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter());
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter(),
|
||||
((PropertyAccessorDescriptor) functionDescriptor)
|
||||
.getCorrespondingProperty());
|
||||
}
|
||||
else if (functionDescriptor instanceof SimpleFunctionDescriptor) {
|
||||
if (propertyTypeSignature != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
aw.writeFlags();
|
||||
if (CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) {
|
||||
aw.writeFlags(modality == Modality.FINAL
|
||||
? JvmStdlibNames.JET_METHOD_FLAG_FORCE_FINAL_BIT
|
||||
: JvmStdlibNames.JET_METHOD_FLAG_FORCE_OPEN_BIT);
|
||||
}
|
||||
else {
|
||||
aw.writeFlags();
|
||||
}
|
||||
aw.writeNullableReturnType(functionDescriptor.getReturnType().isNullable());
|
||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
||||
|
||||
@@ -334,7 +334,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
|
||||
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||
original);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
}
|
||||
@@ -360,7 +362,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
|
||||
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||
original);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,8 @@ public class PropertyCodegen {
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
String getterName = getterName(propertyDescriptor.getName());
|
||||
MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null);
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
|
||||
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor);
|
||||
|
||||
if (propertyDescriptor.getGetter() != null) {
|
||||
assert !propertyDescriptor.getGetter().hasBody();
|
||||
@@ -221,9 +222,19 @@ public class PropertyCodegen {
|
||||
FunctionCodegen.endVisit(mv, "getter", origin);
|
||||
}
|
||||
|
||||
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters) {
|
||||
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters,
|
||||
@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
aw.writeFlags(JvmStdlibNames.JET_METHOD_FLAG_PROPERTY_BIT);
|
||||
Modality modality = propertyDescriptor.getModality();
|
||||
if (CodegenUtil.isInterface(propertyDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) {
|
||||
aw.writeFlags(JvmStdlibNames.JET_METHOD_FLAG_PROPERTY_BIT,
|
||||
modality == Modality.FINAL
|
||||
? JvmStdlibNames.JET_METHOD_FLAG_FORCE_FINAL_BIT
|
||||
: JvmStdlibNames.JET_METHOD_FLAG_FORCE_OPEN_BIT);
|
||||
}
|
||||
else {
|
||||
aw.writeFlags(JvmStdlibNames.JET_METHOD_FLAG_PROPERTY_BIT);
|
||||
}
|
||||
aw.writeTypeParameters(typeParameters);
|
||||
aw.writePropertyType(kotlinType);
|
||||
aw.visitEnd();
|
||||
@@ -264,7 +275,8 @@ public class PropertyCodegen {
|
||||
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null);
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter());
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
|
||||
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor);
|
||||
|
||||
if (propertyDescriptor.getSetter() != null) {
|
||||
assert !propertyDescriptor.getSetter().hasBody();
|
||||
|
||||
+16
-11
@@ -1340,19 +1340,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
isVar = members.setter != null;
|
||||
}
|
||||
|
||||
Modality modality;
|
||||
if (isFinal) {
|
||||
modality = Modality.FINAL;
|
||||
}
|
||||
else {
|
||||
modality = anyMember.getMember().isAbstract() ? Modality.ABSTRACT : Modality.OPEN;
|
||||
}
|
||||
|
||||
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
owner,
|
||||
resolveAnnotations(anyMember.getMember().psiMember),
|
||||
modality,
|
||||
resolveModality(anyMember.getMember(), isFinal),
|
||||
resolveVisibilityFromPsiModifiers(anyMember.getMember().psiMember),
|
||||
isVar,
|
||||
false,
|
||||
@@ -1658,7 +1649,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
methodTypeParameters,
|
||||
valueParameterDescriptors.descriptors,
|
||||
returnType,
|
||||
Modality.convertFromFlags(method.getPsiMethod().hasModifierProperty(PsiModifier.ABSTRACT), !method.isFinal()),
|
||||
resolveModality(method, method.isFinal()),
|
||||
resolveVisibilityFromPsiModifiers(method.getPsiMethod()),
|
||||
/*isInline = */ false
|
||||
);
|
||||
@@ -1845,6 +1836,20 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
}
|
||||
}
|
||||
|
||||
private static Modality resolveModality(PsiMemberWrapper memberWrapper, boolean isFinal) {
|
||||
if (memberWrapper instanceof PsiMethodWrapper) {
|
||||
PsiMethodWrapper method = (PsiMethodWrapper) memberWrapper;
|
||||
if (method.getJetMethod().flags().get(JvmStdlibNames.JET_METHOD_FLAG_FORCE_OPEN_BIT)) {
|
||||
return Modality.OPEN;
|
||||
}
|
||||
if (method.getJetMethod().flags().get(JvmStdlibNames.JET_METHOD_FLAG_FORCE_FINAL_BIT)) {
|
||||
return Modality.FINAL;
|
||||
}
|
||||
}
|
||||
|
||||
return Modality.convertFromFlags(memberWrapper.isAbstract(), !isFinal);
|
||||
}
|
||||
|
||||
private static Visibility resolveVisibilityFromPsiModifiers(PsiModifierListOwner modifierListOwner) {
|
||||
return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibilities.PUBLIC :
|
||||
(modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibilities.PRIVATE :
|
||||
|
||||
@@ -49,8 +49,10 @@ public class JvmStdlibNames {
|
||||
public static final String JET_METHOD_PROPERTY_TYPE_FIELD = "propertyType";
|
||||
|
||||
public static final int JET_METHOD_FLAGS_DEFAULT_VALUE = 0;
|
||||
public static final int JET_METHOD_FLAGS_BITS = 1;
|
||||
public static final int JET_METHOD_FLAGS_BITS = 3;
|
||||
public static final int JET_METHOD_FLAG_PROPERTY_BIT = 0;
|
||||
public static final int JET_METHOD_FLAG_FORCE_OPEN_BIT = 1;
|
||||
public static final int JET_METHOD_FLAG_FORCE_FINAL_BIT = 2;
|
||||
|
||||
public static final JvmClassName JET_CONSTRUCTOR = JvmClassName.byFqNameWithoutInnerClasses("jet.runtime.typeinfo.JetConstructor");
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// KT-2228
|
||||
|
||||
package test
|
||||
|
||||
trait A {
|
||||
final fun f(): String = "test"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.A : jet.Any {
|
||||
final fun f(): jet.String
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// KT-2228
|
||||
|
||||
package test
|
||||
|
||||
trait A {
|
||||
fun f(): String = "test"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.A : jet.Any {
|
||||
open fun f(): jet.String
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// KT-2228
|
||||
|
||||
package test
|
||||
|
||||
trait A {
|
||||
var v: String
|
||||
get() = "test"
|
||||
set(value) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.A : jet.Any {
|
||||
open var v: jet.String
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// KT-2228
|
||||
|
||||
package test
|
||||
|
||||
trait A {
|
||||
val v: String
|
||||
get() = "test"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.A : jet.Any {
|
||||
open val v: jet.String
|
||||
}
|
||||
Reference in New Issue
Block a user