Move JVM-specific annotations out of built-ins
Move 'volatile' and 'synchronized' to package 'kotlin' in stdlib. Also delete 'atomic', since its support was never implemented
This commit is contained in:
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.psi.JetClass;
|
|||||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||||
@@ -45,6 +46,8 @@ import java.util.*;
|
|||||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
||||||
|
|
||||||
public abstract class AnnotationCodegen {
|
public abstract class AnnotationCodegen {
|
||||||
|
public static final FqName VOLATILE_FQ_NAME = new FqName("kotlin.volatile");
|
||||||
|
|
||||||
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM4) {};
|
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM4) {};
|
||||||
|
|
||||||
private final JetTypeMapper typeMapper;
|
private final JetTypeMapper typeMapper;
|
||||||
@@ -149,7 +152,7 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
private static boolean isVolatile(@NotNull AnnotationDescriptor annotationDescriptor) {
|
private static boolean isVolatile(@NotNull AnnotationDescriptor annotationDescriptor) {
|
||||||
ClassifierDescriptor classDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor classDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
|
||||||
return KotlinBuiltIns.getInstance().getVolatileAnnotationClass().equals(classDescriptor);
|
return classDescriptor != null && DescriptorUtils.getFqName(classDescriptor).equals(VOLATILE_FQ_NAME.toUnsafe());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateAnnotationDefaultValue(@NotNull CompileTimeConstant value, @NotNull JetType expectedType) {
|
public void generateAnnotationDefaultValue(@NotNull CompileTimeConstant value, @NotNull JetType expectedType) {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||||
@@ -180,7 +179,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
private FieldVisitor generateBackingField(JetNamedDeclaration element, PropertyDescriptor propertyDescriptor, boolean isDelegate, JetType jetType, Object defaultValue) {
|
private FieldVisitor generateBackingField(JetNamedDeclaration element, PropertyDescriptor propertyDescriptor, boolean isDelegate, JetType jetType, Object defaultValue) {
|
||||||
int modifiers = getDeprecatedAccessFlag(propertyDescriptor);
|
int modifiers = getDeprecatedAccessFlag(propertyDescriptor);
|
||||||
|
|
||||||
if (KotlinBuiltIns.getInstance().isVolatile(propertyDescriptor)) {
|
if (propertyDescriptor.getOriginal().getAnnotations().findAnnotation(AnnotationCodegen.VOLATILE_FQ_NAME) != null) {
|
||||||
modifiers |= ACC_VOLATILE;
|
modifiers |= ACC_VOLATILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,6 @@ public class IntrinsicMethods {
|
|||||||
private static final ArraySet ARRAY_SET = new ArraySet();
|
private static final ArraySet ARRAY_SET = new ArraySet();
|
||||||
private static final ArrayGet ARRAY_GET = new ArrayGet();
|
private static final ArrayGet ARRAY_GET = new ArrayGet();
|
||||||
private static final StringPlus STRING_PLUS = new StringPlus();
|
private static final StringPlus STRING_PLUS = new StringPlus();
|
||||||
private static final String KOTLIN_JAVA_CLASS_FUNCTION = "kotlin.javaClass.function";
|
|
||||||
private static final String KOTLIN_JAVA_CLASS_PROPERTY = "kotlin.javaClass.property";
|
|
||||||
private static final String KOTLIN_ARRAYS_ARRAY = "kotlin.arrays.array";
|
|
||||||
private static final String KOTLIN_COPY_TO_ARRAY = "kotlin.collections.copyToArray";
|
|
||||||
private static final EnumValues ENUM_VALUES = new EnumValues();
|
private static final EnumValues ENUM_VALUES = new EnumValues();
|
||||||
private static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf();
|
private static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf();
|
||||||
private static final ToString TO_STRING = new ToString();
|
private static final ToString TO_STRING = new ToString();
|
||||||
@@ -70,13 +66,13 @@ public class IntrinsicMethods {
|
|||||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||||
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
|
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
|
||||||
|
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
namedMethods.put(KOTLIN_JAVA_CLASS_FUNCTION, new JavaClassFunction());
|
namedMethods.put("kotlin.javaClass.function", new JavaClassFunction());
|
||||||
namedMethods.put(KOTLIN_JAVA_CLASS_PROPERTY, new JavaClassProperty());
|
namedMethods.put("kotlin.javaClass.property", new JavaClassProperty());
|
||||||
namedMethods.put(KOTLIN_ARRAYS_ARRAY, new JavaClassArray());
|
namedMethods.put("kotlin.arrays.array", new JavaClassArray());
|
||||||
namedMethods.put(KOTLIN_COPY_TO_ARRAY, new CopyToArray());
|
namedMethods.put("kotlin.collections.copyToArray", new CopyToArray());
|
||||||
|
namedMethods.put("kotlin.synchronized", new StupidSync());
|
||||||
|
|
||||||
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||||
for (Name method : primitiveCastMethods) {
|
for (Name method : primitiveCastMethods) {
|
||||||
@@ -126,7 +122,6 @@ public class IntrinsicMethods {
|
|||||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("identityEquals"), 1, IDENTITY_EQUALS);
|
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("identityEquals"), 1, IDENTITY_EQUALS);
|
||||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("plus"), 1, STRING_PLUS);
|
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("plus"), 1, STRING_PLUS);
|
||||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("arrayOfNulls"), 1, new NewArray());
|
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("arrayOfNulls"), 1, new NewArray());
|
||||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("synchronized"), 2, new StupidSync());
|
|
||||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("iterator"), 0, new IteratorIterator());
|
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier("iterator"), 0, new IteratorIterator());
|
||||||
|
|
||||||
for (PrimitiveType type : PrimitiveType.values()) {
|
for (PrimitiveType type : PrimitiveType.values()) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package-fragment jet
|
package-fragment jet
|
||||||
|
|
||||||
public fun </*0*/ T> arrayOfNulls(/*0*/ size: jet.Int): jet.Array<T?>
|
public fun </*0*/ T> arrayOfNulls(/*0*/ size: jet.Int): jet.Array<T?>
|
||||||
public fun </*0*/ R> synchronized(/*0*/ lock: jet.Any, /*1*/ block: jet.Function0<R>): R
|
|
||||||
public fun jet.Any?.equals(/*0*/ other: jet.Any?): jet.Boolean
|
public fun jet.Any?.equals(/*0*/ other: jet.Any?): jet.Boolean
|
||||||
public fun jet.Any?.identityEquals(/*0*/ other: jet.Any?): jet.Boolean
|
public fun jet.Any?.identityEquals(/*0*/ other: jet.Any?): jet.Boolean
|
||||||
public fun </*0*/ T> jet.Iterator<T>.iterator(): jet.Iterator<T>
|
public fun </*0*/ T> jet.Iterator<T>.iterator(): jet.Iterator<T>
|
||||||
@@ -1687,10 +1686,6 @@ public final class Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final annotation class atomic : jet.Annotation {
|
|
||||||
/*primary*/ public constructor atomic()
|
|
||||||
}
|
|
||||||
|
|
||||||
public final annotation class data : jet.Annotation {
|
public final annotation class data : jet.Annotation {
|
||||||
/*primary*/ public constructor data()
|
/*primary*/ public constructor data()
|
||||||
}
|
}
|
||||||
@@ -1720,7 +1715,3 @@ public final annotation class suppress : jet.Annotation {
|
|||||||
public final annotation class tailRecursive : jet.Annotation {
|
public final annotation class tailRecursive : jet.Annotation {
|
||||||
/*primary*/ public constructor tailRecursive()
|
/*primary*/ public constructor tailRecursive()
|
||||||
}
|
}
|
||||||
|
|
||||||
public final annotation class volatile : jet.Annotation {
|
|
||||||
/*primary*/ public constructor volatile()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
||||||
private volatile var value: T? = null
|
private var value: T? = null
|
||||||
|
|
||||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
volatile val foo: Int = 1
|
volatile val foo: Int = 1
|
||||||
|
|
||||||
// 0 jet/volatile
|
// 0 kotlin/volatile
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
||||||
private volatile var value: T? = null
|
private var value: T? = null
|
||||||
|
|
||||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
public open class TestDelegate<T: Any>(private val initializer: () -> T) {
|
||||||
private volatile var value: T? = null
|
private var value: T? = null
|
||||||
|
|
||||||
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
public open fun get(thisRef: Any?, desc: PropertyMetadata): T {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public abstract class AbstractBytecodeTextTest extends CodegenTestCase {
|
|||||||
private static final Pattern EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$");
|
private static final Pattern EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$");
|
||||||
|
|
||||||
public void doTest(@NotNull String filename) throws Exception {
|
public void doTest(@NotNull String filename) throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL);
|
||||||
loadFileByFullPath(filename);
|
loadFileByFullPath(filename);
|
||||||
List<OccurrenceInfo> expected = readExpectedOccurrences(filename);
|
List<OccurrenceInfo> expected = readExpectedOccurrences(filename);
|
||||||
countAndCompareActualOccurrences(expected);
|
countAndCompareActualOccurrences(expected);
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class AnnotationGenTest extends CodegenTestCase {
|
public class AnnotationGenTest extends CodegenTestCase {
|
||||||
|
|
||||||
@@ -49,6 +47,13 @@ public class AnnotationGenTest extends CodegenTestCase {
|
|||||||
return loader.loadClass(PackageCodegen.getPackagePartInternalName(myFiles.getPsiFile()));
|
return loader.loadClass(PackageCodegen.getPackagePartInternalName(myFiles.getPsiFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testVolatileProperty() throws Exception {
|
||||||
|
loadText("abstract class Foo { public volatile var x: String = \"\"; }");
|
||||||
|
Class<?> aClass = generateClass("Foo");
|
||||||
|
Field x = aClass.getDeclaredField("x");
|
||||||
|
assertTrue((x.getModifiers() & Modifier.VOLATILE) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void testPropField() throws Exception {
|
public void testPropField() throws Exception {
|
||||||
ClassLoader loader = loadFileGetClassLoader("[Deprecated] var x = 0");
|
ClassLoader loader = loadFileGetClassLoader("[Deprecated] var x = 0");
|
||||||
Class<?> packageClass = getPackageClass(loader);
|
Class<?> packageClass = getPackageClass(loader);
|
||||||
|
|||||||
@@ -159,13 +159,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
|||||||
assertNotNull(aClass.getMethod("getX"));
|
assertNotNull(aClass.getMethod("getX"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testVolatileProperty() throws Exception {
|
|
||||||
loadText("abstract class Foo { public volatile var x: String = \"\"; }");
|
|
||||||
Class aClass = generateClass("Foo");
|
|
||||||
Field x = aClass.getDeclaredField("x");
|
|
||||||
assertTrue((x.getModifiers() & Modifier.VOLATILE) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testKt160() throws Exception {
|
public void testKt160() throws Exception {
|
||||||
loadText("internal val s = java.lang.Double.toString(1.0)");
|
loadText("internal val s = java.lang.Double.toString(1.0)");
|
||||||
Method method = generateFunction("getS");
|
Method method = generateFunction("getS");
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ package jet
|
|||||||
|
|
||||||
public trait Annotation
|
public trait Annotation
|
||||||
|
|
||||||
public annotation class volatile
|
|
||||||
|
|
||||||
public fun <R> synchronized(lock: Any, block: () -> R): R
|
|
||||||
|
|
||||||
public fun Any?.identityEquals(other: Any?): Boolean // = this === other
|
public fun Any?.identityEquals(other: Any?): Boolean // = this === other
|
||||||
|
|
||||||
public fun Any?.equals(other: Any?): Boolean
|
public fun Any?.equals(other: Any?): Boolean
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package jet
|
package jet
|
||||||
|
|
||||||
public annotation class atomic
|
|
||||||
public annotation class data
|
public annotation class data
|
||||||
|
|
||||||
public annotation class deprecated(val value: String)
|
public annotation class deprecated(val value: String)
|
||||||
|
|
||||||
public annotation class suppress(vararg val names: String)
|
public annotation class suppress(vararg val names: String)
|
||||||
|
|
||||||
public annotation class tailRecursive
|
public annotation class tailRecursive
|
||||||
|
|||||||
@@ -361,11 +361,6 @@ public class KotlinBuiltIns {
|
|||||||
return getBuiltInClassByName("suppress");
|
return getBuiltInClassByName("suppress");
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ClassDescriptor getVolatileAnnotationClass() {
|
|
||||||
return getBuiltInClassByName("volatile");
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassDescriptor getTailRecursiveAnnotationClass() {
|
public ClassDescriptor getTailRecursiveAnnotationClass() {
|
||||||
return getBuiltInClassByName("tailRecursive");
|
return getBuiltInClassByName("tailRecursive");
|
||||||
@@ -528,7 +523,6 @@ public class KotlinBuiltIns {
|
|||||||
getMutableMap(),
|
getMutableMap(),
|
||||||
getMutableMapEntry(),
|
getMutableMapEntry(),
|
||||||
|
|
||||||
getVolatileAnnotationClass(),
|
|
||||||
getDataClassAnnotation(),
|
getDataClassAnnotation(),
|
||||||
getAnnotation(),
|
getAnnotation(),
|
||||||
getComparable(),
|
getComparable(),
|
||||||
@@ -950,10 +944,6 @@ public class KotlinBuiltIns {
|
|||||||
return descriptor.getOriginal().getAnnotations().findAnnotation(fqName) != null;
|
return descriptor.getOriginal().getAnnotations().findAnnotation(fqName) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVolatile(@NotNull PropertyDescriptor descriptor) {
|
|
||||||
return containsAnnotation(descriptor, getVolatileAnnotationClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -25,3 +25,8 @@ public annotation class throws(vararg val exceptionClasses: Class<out Throwable>
|
|||||||
get() = (this as java.lang.Object).getClass() as Class<T>
|
get() = (this as java.lang.Object).getClass() as Class<T>
|
||||||
|
|
||||||
[Intrinsic("kotlin.javaClass.function")] fun <reified T> javaClass() : Class<T> = null as Class<T>
|
[Intrinsic("kotlin.javaClass.function")] fun <reified T> javaClass() : Class<T> = null as Class<T>
|
||||||
|
|
||||||
|
Retention(RetentionPolicy.SOURCE)
|
||||||
|
public annotation class volatile
|
||||||
|
|
||||||
|
[Intrinsic("kotlin.synchronized")] public fun <R> synchronized(lock: Any, block: () -> R): R = block()
|
||||||
|
|||||||
Reference in New Issue
Block a user