Use getfield or putfield instructions for private properties instead of invokevirtual getA or setA
This commit is contained in:
@@ -1537,6 +1537,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (isInsideClass &&
|
if (isInsideClass &&
|
||||||
(propertyDescriptor.getGetter() == null ||
|
(propertyDescriptor.getGetter() == null ||
|
||||||
|
!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
|
||||||
propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
|
propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
|
||||||
getter = null;
|
getter = null;
|
||||||
}
|
}
|
||||||
@@ -1573,6 +1574,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (!propertyDescriptor.isVar() || isInsideClass &&
|
if (!propertyDescriptor.isVar() || isInsideClass &&
|
||||||
(propertyDescriptor.getSetter() == null ||
|
(propertyDescriptor.getSetter() == null ||
|
||||||
|
!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
|
||||||
propertyDescriptor.getSetter().isDefault() &&
|
propertyDescriptor.getSetter().isDefault() &&
|
||||||
propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
||||||
setter = null;
|
setter = null;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import static org.jetbrains.asm4.Opcodes.*;
|
|||||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isExternallyAccessible;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,11 +141,6 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isExternallyAccessible(PropertyDescriptor p) {
|
|
||||||
return p.getVisibility() != Visibilities.PRIVATE || DescriptorUtils.isClassObject(p.getContainingDeclaration())
|
|
||||||
|| p.getContainingDeclaration() instanceof NamespaceDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
||||||
JetPropertyAccessor setter = p.getSetter();
|
JetPropertyAccessor setter = p.getSetter();
|
||||||
if (setter != null && setter.getBodyExpression() != null) {
|
if (setter != null && setter.getBodyExpression() != null) {
|
||||||
|
|||||||
@@ -386,4 +386,9 @@ public class DescriptorUtils {
|
|||||||
return receiverParameterDescriptor.getValue();
|
return receiverParameterDescriptor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isExternallyAccessible(PropertyDescriptor propertyDescriptor) {
|
||||||
|
return propertyDescriptor.getVisibility() != Visibilities.PRIVATE || isClassObject(propertyDescriptor.getContainingDeclaration())
|
||||||
|
|| propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
class A {
|
||||||
|
private var foo = 1
|
||||||
|
get() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
foo = 5
|
||||||
|
foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
private val foo = 1
|
||||||
|
get
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
private var foo = 1
|
||||||
|
get
|
||||||
|
set
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
foo = 2
|
||||||
|
foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D {
|
||||||
|
private var foo = 1
|
||||||
|
set(i: Int) {
|
||||||
|
foo = i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
foo = 5
|
||||||
|
foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
A().foo()
|
||||||
|
B().foo()
|
||||||
|
C().foo()
|
||||||
|
D().foo()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class D {
|
||||||
|
var foo = 1
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
foo = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
D().foo()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -366,4 +366,14 @@ public class PropertyGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("properties/kt2892.kt");
|
blackBoxFile("properties/kt2892.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAccessToPrivateProperty() throws Exception {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("properties/accessToPrivateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAccessToPrivateSetter() throws Exception {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("properties/accessToPrivateSetter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user