Use getfield or putfield instructions for private properties instead of invokevirtual getA or setA

This commit is contained in:
Natalia.Ukhorskaya
2012-11-01 15:50:58 +04:00
parent ec255e8342
commit 481afeb914
6 changed files with 83 additions and 5 deletions
@@ -1537,6 +1537,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
//noinspection ConstantConditions
if (isInsideClass &&
(propertyDescriptor.getGetter() == null ||
!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
getter = null;
}
@@ -1573,6 +1574,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
//noinspection ConstantConditions
if (!propertyDescriptor.isVar() || isInsideClass &&
(propertyDescriptor.getSetter() == null ||
!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
propertyDescriptor.getSetter().isDefault() &&
propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
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.CodegenUtil.*;
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;
/**
@@ -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) {
JetPropertyAccessor setter = p.getSetter();
if (setter != null && setter.getBodyExpression() != null) {
@@ -386,4 +386,9 @@ public class DescriptorUtils {
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");
}
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");
}
}