diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index c8c9f3dee79..8ea5e7fd350 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -68,6 +68,10 @@ public class FunctionCodegen { { flags |= ACC_VARARGS; } + + if (functionDescriptor.getModality() == Modality.FINAL) { + flags |= ACC_FINAL; + } OwnerKind kind = context.getContextKind(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 852b12ac22e..f1535c8f16a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -47,19 +47,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { boolean isAbstract = false; boolean isInterface = false; + boolean isFinal = false; if(myClass instanceof JetClass) { - if(((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)) + JetClass jetClass = (JetClass) myClass; + if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) isAbstract = true; - if(((JetClass) myClass).isTrait()) { + if (jetClass.isTrait()) { isAbstract = true; isInterface = true; } + if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD)) { + isFinal = true; + } } + int access = 0; + access |= Opcodes.ACC_PUBLIC; + if (isAbstract) { + access |= Opcodes.ACC_ABSTRACT; + } + if (isInterface) { + access |= Opcodes.ACC_INTERFACE; // ACC_SUPER + } + if (isFinal) { + access |= Opcodes.ACC_FINAL; + } v.defineClass(myClass, Opcodes.V1_6, - Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface - ? Opcodes.ACC_INTERFACE - : 0/*Opcodes.ACC_SUPER*/), + access, signature.getName(), signature.getJavaGenericSignature(), signature.getSuperclassName(), diff --git a/compiler/testData/readClass/fun/ModifierAbstract.kt b/compiler/testData/readClass/fun/ModifierAbstract.kt new file mode 100644 index 00000000000..3800def1fad --- /dev/null +++ b/compiler/testData/readClass/fun/ModifierAbstract.kt @@ -0,0 +1,5 @@ +namespace test + +abstract class ModifierAbstract { + abstract fun abs(): Int +} diff --git a/compiler/testData/readClass/fun/ModifierOpen.kt b/compiler/testData/readClass/fun/ModifierOpen.kt new file mode 100644 index 00000000000..e9f15a08e07 --- /dev/null +++ b/compiler/testData/readClass/fun/ModifierOpen.kt @@ -0,0 +1,5 @@ +namespace test + +open class ModifierOpen { + open fun abs() = 1 +} diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index c653d33579d..e8fbc7679c6 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -146,6 +146,10 @@ public class ReadClassDataTest extends UsefulTestCase { private String serializeContent(ClassDescriptor klass) { StringBuilder sb = new StringBuilder(); + + serialize(klass.getModality(), sb); + sb.append(" "); + serialize(klass.getKind(), sb); sb.append(" "); @@ -221,6 +225,9 @@ public class ReadClassDataTest extends UsefulTestCase { private void serialize(FunctionDescriptor fun, StringBuilder sb) { + serialize(fun.getModality(), sb); + sb.append(" "); + sb.append("fun "); if (!fun.getTypeParameters().isEmpty()) { sb.append("<"); @@ -278,7 +285,11 @@ public class ReadClassDataTest extends UsefulTestCase { sb.append(variance); sb.append(' '); } - } + } + + private void serialize(Modality modality, StringBuilder sb) { + sb.append(modality.name().toLowerCase()); + } private void serialize(JetType type, StringBuilder sb) { serialize(type.getConstructor().getDeclarationDescriptor(), sb);