diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 691f904dd92..980c3f009fd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -76,6 +76,9 @@ public class PropertyCodegen { if (!propertyDescriptor.isVar()) { modifiers |= Opcodes.ACC_FINAL; } + if(state.getStandardLibrary().isVolatile(propertyDescriptor)) { + modifiers |= Opcodes.ACC_VOLATILE; + } v.newField(p, modifiers, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, value); } } diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index a418ea65c7b..1b0311b49a6 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -8,6 +8,8 @@ class TypeInfo { fun typeinfo() : TypeInfo fun typeinfo(expression : T) : TypeInfo +annotation class volatile + fun synchronized(lock: Any, block : () -> R) : R fun Any?.identityEquals(other : Any?) : Boolean // = this === other diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 02f8c9cd427..f6ac9c69ba9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; @@ -61,8 +62,10 @@ public class JetStandardLibrary { private ClassDescriptor iterableClass; private ClassDescriptor typeInfoClass; private ClassDescriptor comparableClass; + private ClassDescriptor volatileClass; private JetType stringType; + private JetType volatileType; private JetType nullableStringType; private JetType charSequenceType; private JetType nullableCharSequenceType; @@ -138,6 +141,7 @@ public class JetStandardLibrary { this.stringClass = (ClassDescriptor) libraryScope.getClassifier("String"); this.charSequenceClass = (ClassDescriptor) libraryScope.getClassifier("CharSequence"); this.arrayClass = (ClassDescriptor) libraryScope.getClassifier("Array"); + this.volatileClass = (ClassDescriptor) libraryScope.getClassifier("volatile"); this.iterableClass = (ClassDescriptor) libraryScope.getClassifier("Iterable"); this.comparableClass = (ClassDescriptor) libraryScope.getClassifier("Comparable"); @@ -149,6 +153,7 @@ public class JetStandardLibrary { this.charSequenceType = new JetTypeImpl(getCharSequence()); this.nullableCharSequenceType = TypeUtils.makeNullable(charSequenceType); this.nullableStringType = TypeUtils.makeNullable(stringType); + this.volatileType = new JetTypeImpl(getVolatile()); this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0)); this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type); @@ -445,4 +450,22 @@ public class JetStandardLibrary { return primitiveTypeToNullableArrayJetType.get(primitiveType); } + public ClassDescriptor getVolatile() { + return volatileClass; + } + + public JetType getVolatileType() { + return volatileType; + } + + public final boolean isVolatile(PropertyDescriptor descriptor) { + List annotations = descriptor.getOriginal().getAnnotations(); + if(annotations != null) { + for(AnnotationDescriptor d: annotations) { + if(d.getType().equals(getVolatileType())) + return true; + } + } + return false; + } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java index 9cd14366834..8ea823b65d0 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java @@ -149,6 +149,15 @@ public class PropertyGenTest extends CodegenTestCase { assertNotNull(aClass.getMethod("getX")); } + public void testVolatileProperty() throws Exception { + loadText("abstract class Foo { public volatile var x: String = \"\"; }"); + System.out.println(generateToText()); + final ClassFileFactory codegens = generateClassesInFile(); + final Class aClass = loadClass("Foo", codegens); + Field x = aClass.getDeclaredField("x"); + assertTrue((x.getModifiers() & Modifier.VOLATILE) != 0); + } + public void testKt257 () throws Exception { blackBoxFile("regressions/kt257.jet"); // System.out.println(generateToText());