Generate 'Deprecated' annotation on invisible companion object field
Design decision: if the field for a companion object should have non-public visibility, generate it with @Deprecated annotation in language version 1.2. TODO: generate it with proper visibility in 1.3 and later. KT-11567 Companion object INSTANCE field more visible than companion object class itself
This commit is contained in:
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
|||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
@@ -64,10 +65,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
@@ -838,9 +836,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Nullable KtObjectDeclaration companionObject = CollectionsKt.firstOrNull(myClass.getCompanionObjects());
|
@Nullable KtObjectDeclaration companionObject = CollectionsKt.firstOrNull(myClass.getCompanionObjects());
|
||||||
|
|
||||||
|
int properFieldVisibilityFlag = getVisibilityAccessFlag(companionObjectDescriptor);
|
||||||
|
boolean fieldShouldBeDeprecated =
|
||||||
|
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.DeprecatedFieldForInvisibleCompanionObject) &&
|
||||||
|
(properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
|
||||||
|
// TODO generate field with proper visibility in language version 1.3
|
||||||
|
int fieldAccessFlags = ACC_PUBLIC | ACC_STATIC | ACC_FINAL;
|
||||||
|
if (fieldShouldBeDeprecated) {
|
||||||
|
fieldAccessFlags |= ACC_DEPRECATED;
|
||||||
|
}
|
||||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
||||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null);
|
||||||
|
if (fieldShouldBeDeprecated) {
|
||||||
|
AnnotationCodegen.forField(fv, this, typeMapper).visitAnnotation("Ljava/lang/Deprecated;", true).visitEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateCompanionObjectBackingFieldCopies() {
|
private void generateCompanionObjectBackingFieldCopies() {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// LANGUAGE_VERSION: 1.2
|
||||||
|
|
||||||
|
class TestPrivateCompanion {
|
||||||
|
private companion object Test
|
||||||
|
}
|
||||||
|
|
||||||
|
open class TestProtectedCompanion {
|
||||||
|
protected companion object Test
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestInternalCompanion {
|
||||||
|
internal companion object Test
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestInternalCompanion$Test {
|
||||||
|
inner class TestInternalCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestInternalCompanion {
|
||||||
|
public final static field Test: TestInternalCompanion$Test
|
||||||
|
inner class TestInternalCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
final class TestPrivateCompanion$Test {
|
||||||
|
inner class TestPrivateCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestPrivateCompanion {
|
||||||
|
public deprecated final static @java.lang.Deprecated field Test: TestPrivateCompanion$Test
|
||||||
|
inner class TestPrivateCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestProtectedCompanion$Test {
|
||||||
|
inner class TestProtectedCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestProtectedCompanion {
|
||||||
|
public deprecated final static @java.lang.Deprecated field Test: TestProtectedCompanion$Test
|
||||||
|
inner class TestProtectedCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// LANGUAGE_VERSION: 1.1
|
||||||
|
|
||||||
|
class TestPrivateCompanion {
|
||||||
|
private companion object Test
|
||||||
|
}
|
||||||
|
|
||||||
|
open class TestProtectedCompanion {
|
||||||
|
protected companion object Test
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestInternalCompanion {
|
||||||
|
internal companion object Test
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestInternalCompanion$Test {
|
||||||
|
inner class TestInternalCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestInternalCompanion {
|
||||||
|
public final static field Test: TestInternalCompanion$Test
|
||||||
|
inner class TestInternalCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
final class TestPrivateCompanion$Test {
|
||||||
|
inner class TestPrivateCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestPrivateCompanion {
|
||||||
|
public final static field Test: TestPrivateCompanion$Test
|
||||||
|
inner class TestPrivateCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestProtectedCompanion$Test {
|
||||||
|
inner class TestProtectedCompanion$Test
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestProtectedCompanion {
|
||||||
|
public final static field Test: TestProtectedCompanion$Test
|
||||||
|
inner class TestProtectedCompanion$Test
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
@@ -90,6 +90,18 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("invisibleCompanionObject.kt")
|
||||||
|
public void testInvisibleCompanionObject() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/invisibleCompanionObject.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("invisibleCompanionObject_lv11.kt")
|
||||||
|
public void testInvisibleCompanionObject_lv11() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/invisibleCompanionObject_lv11.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jvmOverloadsAndParametersAnnotations.kt")
|
@TestMetadata("jvmOverloadsAndParametersAnnotations.kt")
|
||||||
public void testJvmOverloadsAndParametersAnnotations() throws Exception {
|
public void testJvmOverloadsAndParametersAnnotations() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/jvmOverloadsAndParametersAnnotations.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/jvmOverloadsAndParametersAnnotations.kt");
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ enum class LanguageFeature(
|
|||||||
ArrayLiteralsInAnnotations(KOTLIN_1_2),
|
ArrayLiteralsInAnnotations(KOTLIN_1_2),
|
||||||
InlineDefaultFunctionalParameters(KOTLIN_1_2),
|
InlineDefaultFunctionalParameters(KOTLIN_1_2),
|
||||||
SoundSmartCastsAfterTry(KOTLIN_1_2),
|
SoundSmartCastsAfterTry(KOTLIN_1_2),
|
||||||
|
DeprecatedFieldForInvisibleCompanionObject(KOTLIN_1_2),
|
||||||
|
|
||||||
// Experimental features
|
// Experimental features
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user