Don't generate accessors for @JvmField properties in primary constructor

This commit is contained in:
Michael Bogdanov
2015-11-28 14:17:16 +03:00
parent de37cb8f40
commit 1bf521c645
9 changed files with 80 additions and 21 deletions
@@ -118,16 +118,7 @@ public class PropertyCodegen {
if (CodegenContextUtil.isImplClassOwner(context)) {
assert declaration != null : "Declaration is null for different context: " + context;
boolean hasBackingField = hasBackingField(declaration, descriptor);
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(false, descriptor.isVar(), hasBackingField));
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
generateBackingField(declaration, descriptor, fieldAnnotations);
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
genBackingFieldAndAnnotations(declaration, descriptor, false);
}
if (isAccessorNeeded(declaration, descriptor, getter)) {
@@ -140,6 +131,21 @@ public class PropertyCodegen {
context.recordSyntheticAccessorIfNeeded(descriptor, bindingContext);
}
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
boolean hasBackingField = hasBackingField(declaration, descriptor);
AnnotationSplitter annotationSplitter =
AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
descriptor.getAnnotations(),
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField));
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
generateBackingField(declaration, descriptor, fieldAnnotations);
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
}
/**
* Determines if it's necessary to generate an accessor to the property, i.e. if this property can be referenced via getter/setter
* for any reason
@@ -174,21 +180,20 @@ public class PropertyCodegen {
return true;
}
public void generatePrimaryConstructorProperty(KtParameter p, PropertyDescriptor descriptor) {
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(true, descriptor.isVar(), hasBackingField(p, descriptor)));
private static boolean areAccessorsNeededForPrimaryConstructorProperty(
@NotNull PropertyDescriptor descriptor
) {
if (hasJvmFieldAnnotation(descriptor)) return false;
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
return !Visibilities.isPrivate(descriptor.getVisibility());
}
generateBackingField(p, descriptor, fieldAnnotations);
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
public void generatePrimaryConstructorProperty(@NotNull KtParameter p, @NotNull PropertyDescriptor descriptor) {
genBackingFieldAndAnnotations(p, descriptor, true);
if (!Visibilities.isPrivate(descriptor.getVisibility())) {
if (areAccessorsNeededForPrimaryConstructorProperty(descriptor)) {
generateGetter(p, descriptor, null);
if (descriptor.isVar()) {
generateSetter(p, descriptor, null);
}
generateSetter(p, descriptor, null);
}
}
@@ -0,0 +1,6 @@
public class Test {
public static String invokeMethodWithPublicField() {
C c = new C("OK");
return c.foo;
}
}
@@ -0,0 +1,7 @@
class C(@JvmField val foo: String) {
}
fun box(): String {
return Test.invokeMethodWithPublicField()
}
+9
View File
@@ -0,0 +1,9 @@
class C(@JvmField var foo: String) {
@JvmField var bar: String = "123"
}
// 0 getFoo
// 0 setFoo
// 0 getBar
// 0 setBar
@@ -0,0 +1,5 @@
open class A(@JvmField public val publicField: String = "1",
@JvmField internal val internalField: String = "2",
@JvmField protected val protectedfield: String = "3")
open class B : A()
@@ -0,0 +1,9 @@
open class C : B() {
fun test(): String {
return super.publicField + super.internalField + super.protectedfield
}
}
fun main(args: Array<String>) {
C().test()
}
@@ -161,6 +161,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName);
}
@TestMetadata("jvmField.kt")
public void testJvmField() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/jvmField.kt");
doTest(fileName);
}
@TestMetadata("kt2202.kt")
public void testKt2202() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt2202.kt");
@@ -393,6 +393,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/jvmField"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("constructorProperty")
public void testConstructorProperty() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/jvmField/constructorProperty/");
doTestWithJava(fileName);
}
@TestMetadata("simple")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/jvmField/simple/");
@@ -107,6 +107,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
doTest(fileName);
}
@TestMetadata("jvmFieldInConstructor.A.kt")
public void testJvmFieldInConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/jvmFieldInConstructor.A.kt");
doTest(fileName);
}
@TestMetadata("JvmNameOnAccessor.A.kt")
public void testJvmNameOnAccessor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/JvmNameOnAccessor.A.kt");