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.*;
|
||||
|
||||
public class FunctionCodegen {
|
||||
private static final String JAVA_LANG_DEPRECATED = Type.getType(Deprecated.class).getDescriptor();
|
||||
|
||||
public final GenerationState state;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
@@ -225,7 +224,7 @@ public class FunctionCodegen {
|
||||
InlineClassDescriptorResolver.isSpecializedEqualsMethod(functionDescriptor);
|
||||
generateMethodAnnotationsIfRequired(
|
||||
functionDescriptor, asmMethod, jvmSignature, mv,
|
||||
isCompatibilityStubInDefaultImpls ? Collections.singletonList(JAVA_LANG_DEPRECATED) : Collections.emptyList(),
|
||||
isCompatibilityStubInDefaultImpls ? Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED) : Collections.emptyList(),
|
||||
skipNullabilityAnnotations
|
||||
);
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
|
||||
@@ -903,19 +903,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
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) {
|
||||
PropertyDescriptor property = info.descriptor;
|
||||
|
||||
Type type = typeMapper.mapType(property);
|
||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
|
||||
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
|
||||
modifiers, context.getFieldName(property, false),
|
||||
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
||||
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,
|
||||
//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.Method;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getDeprecatedAccessFlag;
|
||||
@@ -408,6 +409,7 @@ public class PropertyCodegen {
|
||||
ClassBuilder builder = v;
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
List<String> additionalVisibleAnnotations = Collections.emptyList();
|
||||
if (DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC;
|
||||
|
||||
@@ -415,6 +417,10 @@ public class PropertyCodegen {
|
||||
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
if (DescriptorVisibilities.isPrivate(((ClassDescriptor) propertyDescriptor.getContainingDeclaration()).getVisibility())) {
|
||||
modifiers |= ACC_DEPRECATED;
|
||||
additionalVisibleAnnotations = Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||
@@ -442,7 +448,7 @@ public class PropertyCodegen {
|
||||
(modifiers & ACC_SYNTHETIC) != 0 ||
|
||||
propertyDescriptor.isLateInit();
|
||||
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.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
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.SpecialGenericSignatures.SpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
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.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||
import java.lang.Deprecated
|
||||
import java.util.*
|
||||
|
||||
@JvmField
|
||||
internal val JAVA_LANG_DEPRECATED = Type.getType(Deprecated::class.java).descriptor
|
||||
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
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");
|
||||
}
|
||||
|
||||
@TestMetadata("privateCompanionFields.kt")
|
||||
public void testPrivateCompanionFields() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privateDefaultImpls.kt")
|
||||
public void testPrivateDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
||||
|
||||
+5
@@ -134,6 +134,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
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")
|
||||
public void testPrivateDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultImpls.kt");
|
||||
|
||||
@@ -52,6 +52,16 @@ PsiJetFileStubImpl[package=]
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
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
|
||||
USER_TYPE
|
||||
USER_TYPE
|
||||
|
||||
Reference in New Issue
Block a user