Deprecate public access to @JvmField/const fields in private companions
#KT-25009
This commit is contained in:
@@ -85,7 +85,6 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
|||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class FunctionCodegen {
|
public class FunctionCodegen {
|
||||||
private static final String JAVA_LANG_DEPRECATED = Type.getType(Deprecated.class).getDescriptor();
|
|
||||||
|
|
||||||
public final GenerationState state;
|
public final GenerationState state;
|
||||||
private final KotlinTypeMapper typeMapper;
|
private final KotlinTypeMapper typeMapper;
|
||||||
@@ -225,7 +224,7 @@ public class FunctionCodegen {
|
|||||||
InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor);
|
InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor);
|
||||||
generateMethodAnnotationsIfRequired(
|
generateMethodAnnotationsIfRequired(
|
||||||
functionDescriptor, asmMethod, jvmSignature, mv,
|
functionDescriptor, asmMethod, jvmSignature, mv,
|
||||||
isCompatibilityStubInDefaultImpls ? Collections.singletonList(JAVA_LANG_DEPRECATED) : Collections.emptyList(),
|
isCompatibilityStubInDefaultImpls ? Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED) : Collections.emptyList(),
|
||||||
skipNullabilityAnnotations
|
skipNullabilityAnnotations
|
||||||
);
|
);
|
||||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||||
|
|||||||
@@ -903,19 +903,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateCompanionObjectBackingFieldCopies() {
|
private void generateCompanionObjectBackingFieldCopies() {
|
||||||
if (companionObjectPropertiesToCopy == null) return;
|
if (companionObjectPropertiesToCopy == null || companionObjectPropertiesToCopy.isEmpty()) return;
|
||||||
|
|
||||||
|
boolean isPrivateCompanion =
|
||||||
|
DescriptorVisibilities.isPrivate(
|
||||||
|
((ClassDescriptor) companionObjectPropertiesToCopy.get(0).descriptor.getContainingDeclaration()).getVisibility());
|
||||||
|
|
||||||
|
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (isPrivateCompanion ? ACC_DEPRECATED : 0);
|
||||||
|
List<String> additionalVisibleAnnotations =
|
||||||
|
isPrivateCompanion ? Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED) : Collections.emptyList();
|
||||||
for (PropertyAndDefaultValue info : companionObjectPropertiesToCopy) {
|
for (PropertyAndDefaultValue info : companionObjectPropertiesToCopy) {
|
||||||
PropertyDescriptor property = info.descriptor;
|
PropertyDescriptor property = info.descriptor;
|
||||||
|
|
||||||
Type type = typeMapper.mapType(property);
|
Type type = typeMapper.mapType(property);
|
||||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
|
|
||||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
|
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
|
||||||
modifiers, context.getFieldName(property, false),
|
modifiers, context.getFieldName(property, false),
|
||||||
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
||||||
info.defaultValue);
|
info.defaultValue);
|
||||||
|
|
||||||
AnnotationCodegen.forField(fv, this, state).genAnnotations(property, type, null);
|
AnnotationCodegen.forField(fv, this, state).genAnnotations(property, type, null, null, additionalVisibleAnnotations);
|
||||||
|
|
||||||
//This field are always static and final so if it has constant initializer don't do anything in clinit,
|
//This field are always static and final so if it has constant initializer don't do anything in clinit,
|
||||||
//field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4
|
//field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ 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;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getDeprecatedAccessFlag;
|
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getDeprecatedAccessFlag;
|
||||||
@@ -408,6 +409,7 @@ public class PropertyCodegen {
|
|||||||
ClassBuilder builder = v;
|
ClassBuilder builder = v;
|
||||||
|
|
||||||
FieldOwnerContext backingFieldContext = context;
|
FieldOwnerContext backingFieldContext = context;
|
||||||
|
List<String> additionalVisibleAnnotations = Collections.emptyList();
|
||||||
if (DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
if (DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||||
modifiers |= ACC_STATIC;
|
modifiers |= ACC_STATIC;
|
||||||
|
|
||||||
@@ -415,6 +417,10 @@ public class PropertyCodegen {
|
|||||||
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||||
builder = codegen.v;
|
builder = codegen.v;
|
||||||
backingFieldContext = codegen.context;
|
backingFieldContext = codegen.context;
|
||||||
|
if (DescriptorVisibilities.isPrivate(((ClassDescriptor) propertyDescriptor.getContainingDeclaration()).getVisibility())) {
|
||||||
|
modifiers |= ACC_DEPRECATED;
|
||||||
|
additionalVisibleAnnotations = Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||||
@@ -442,7 +448,7 @@ public class PropertyCodegen {
|
|||||||
(modifiers & ACC_SYNTHETIC) != 0 ||
|
(modifiers & ACC_SYNTHETIC) != 0 ||
|
||||||
propertyDescriptor.isLateInit();
|
propertyDescriptor.isLateInit();
|
||||||
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
||||||
.genAnnotations(annotatedField, type, propertyDescriptor.getType());
|
.genAnnotations(annotatedField, type, propertyDescriptor.getType(), null, additionalVisibleAnnotations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.config.isReleaseCoroutines
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.SpecialSignatureInfo
|
|
||||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil
|
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil
|
||||||
|
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures.SpecialSignatureInfo
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -60,8 +60,12 @@ 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
|
||||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||||
|
import java.lang.Deprecated
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
internal val JAVA_LANG_DEPRECATED = Type.getType(Deprecated::class.java).descriptor
|
||||||
|
|
||||||
fun generateIsCheck(
|
fun generateIsCheck(
|
||||||
v: InstructionAdapter,
|
v: InstructionAdapter,
|
||||||
kotlinType: KotlinType,
|
kotlinType: KotlinType,
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
class TestClass {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
@JvmField
|
||||||
|
var test: String = "1"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@java.lang.Deprecated
|
||||||
|
var test2: String = "2"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val test3: String = "3"
|
||||||
|
|
||||||
|
const val testConst = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestConst {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val testConst = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestJvmField {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
@JvmField
|
||||||
|
val test3: String = "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
final class TestClass$Companion {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
private final inner class TestClass$Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TestClass {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
private final static @org.jetbrains.annotations.NotNull field Companion: TestClass$Companion
|
||||||
|
public deprecated static @java.lang.Deprecated @kotlin.jvm.JvmField @org.jetbrains.annotations.NotNull field test2: java.lang.String
|
||||||
|
public deprecated final static @java.lang.Deprecated @kotlin.jvm.JvmField @org.jetbrains.annotations.NotNull field test3: java.lang.String
|
||||||
|
public deprecated static @java.lang.Deprecated @kotlin.jvm.JvmField @org.jetbrains.annotations.NotNull field test: java.lang.String
|
||||||
|
public deprecated final static @java.lang.Deprecated field testConst: int
|
||||||
|
static method <clinit>(): void
|
||||||
|
public method <init>(): void
|
||||||
|
private final inner class TestClass$Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
final class TestConst$Companion {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
synthetic final static field $$INSTANCE: TestConst$Companion
|
||||||
|
public final static field testConst: int
|
||||||
|
static method <clinit>(): void
|
||||||
|
private method <init>(): void
|
||||||
|
public final inner class TestConst$Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public interface TestConst {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
public synthetic final static @org.jetbrains.annotations.NotNull field Companion: TestConst$Companion
|
||||||
|
public deprecated final static @java.lang.Deprecated field testConst: int
|
||||||
|
static method <clinit>(): void
|
||||||
|
public final inner class TestConst$Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
final class TestJvmField$Companion {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
synthetic final static field $$INSTANCE: TestJvmField$Companion
|
||||||
|
private method <init>(): void
|
||||||
|
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||||
|
public final inner class TestJvmField$Companion
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public interface TestJvmField {
|
||||||
|
// source: 'privateCompanionFields.kt'
|
||||||
|
public synthetic final static @org.jetbrains.annotations.NotNull field Companion: TestJvmField$Companion
|
||||||
|
public deprecated final static @java.lang.Deprecated @kotlin.jvm.JvmField @org.jetbrains.annotations.NotNull field test3: java.lang.String
|
||||||
|
static method <clinit>(): void
|
||||||
|
public final inner class TestJvmField$Companion
|
||||||
|
}
|
||||||
+5
@@ -134,6 +134,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateCompanionFields.kt")
|
||||||
|
public void testPrivateCompanionFields() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateDefaultImpls.kt")
|
@TestMetadata("privateDefaultImpls.kt")
|
||||||
public void testPrivateDefaultImpls() throws Exception {
|
public void testPrivateDefaultImpls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
||||||
|
|||||||
+5
@@ -134,6 +134,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/noToArrayInJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateCompanionFields.kt")
|
||||||
|
public void testPrivateCompanionFields() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateDefaultImpls.kt")
|
@TestMetadata("privateDefaultImpls.kt")
|
||||||
public void testPrivateDefaultImpls() throws Exception {
|
public void testPrivateDefaultImpls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ PsiJetFileStubImpl[package=]
|
|||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
USER_TYPE
|
USER_TYPE
|
||||||
REFERENCE_EXPRESSION[referencedName=f]
|
REFERENCE_EXPRESSION[referencedName=f]
|
||||||
|
ANNOTATION_ENTRY[hasValueArguments=false, shortName=Deprecated]
|
||||||
|
ANNOTATION_TARGET[useSiteTarget=FIELD]
|
||||||
|
CONSTRUCTOR_CALLEE
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
USER_TYPE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION[referencedName=java]
|
||||||
|
REFERENCE_EXPRESSION[referencedName=lang]
|
||||||
|
REFERENCE_EXPRESSION[referencedName=Deprecated]
|
||||||
TYPE_REFERENCE
|
TYPE_REFERENCE
|
||||||
USER_TYPE
|
USER_TYPE
|
||||||
USER_TYPE
|
USER_TYPE
|
||||||
|
|||||||
Reference in New Issue
Block a user