Access private class property via field in Evaluate Expression

This commit is contained in:
Alexander Udalov
2014-07-17 16:40:59 +04:00
parent a07909bb52
commit eaeb976903
2 changed files with 16 additions and 11 deletions
@@ -1836,7 +1836,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
boolean isStatic = containingDeclaration instanceof PackageFragmentDescriptor;
boolean isSuper = superExpression != null;
boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context);
boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null;
JetType delegateType = getPropertyDelegateType(propertyDescriptor, bindingContext);
@@ -1861,7 +1860,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
if (!skipPropertyAccessors) {
if (couldUseDirectAccessToProperty(propertyDescriptor, true, isInsideClass, isDelegatedProperty, context)) {
if (couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
callableGetter = null;
}
else {
@@ -1885,7 +1884,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (propertyDescriptor.isVar()) {
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null) {
if (couldUseDirectAccessToProperty(propertyDescriptor, false, isInsideClass, isDelegatedProperty, context)) {
if (couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context)) {
callableSetter = null;
}
else {
@@ -34,6 +34,9 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.codeFragmentUtil.CodeFragmentUtilPackage;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor;
@@ -151,12 +154,11 @@ public class JvmCodegenUtil {
return type.getConstructor().getDeclarationDescriptor().getOriginal() == classifier.getOriginal();
}
public static boolean isCallInsideSameClassAsDeclared(CallableMemberDescriptor declarationDescriptor, CodegenContext context) {
boolean isFakeOverride = declarationDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
boolean isDelegate = declarationDescriptor.getKind() == CallableMemberDescriptor.Kind.DELEGATION;
private static boolean isCallInsideSameClassAsDeclared(@NotNull CallableMemberDescriptor descriptor, @NotNull CodegenContext context) {
boolean isFakeOverride = descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
boolean isDelegate = descriptor.getKind() == CallableMemberDescriptor.Kind.DELEGATION;
DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
containingDeclaration = containingDeclaration.getOriginal();
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration().getOriginal();
return !isFakeOverride && !isDelegate &&
(((context.hasThisDescriptor() && containingDeclaration == context.getThisDescriptor()) ||
@@ -249,7 +251,6 @@ public class JvmCodegenUtil {
public static boolean couldUseDirectAccessToProperty(
@NotNull PropertyDescriptor property,
boolean forGetter,
boolean isInsideClass,
boolean isDelegated,
@NotNull MethodContext context
) {
@@ -258,8 +259,8 @@ public class JvmCodegenUtil {
// Inline functions can't use direct access because a field may not be visible at the call site
if (context.isInlineFunction()) return false;
// Only properties of the same class can be directly accessed
if (!isInsideClass) return false;
// Only properties of the same class can be directly accessed, except when we are evaluating expressions in the debugger
if (!isCallInsideSameClassAsDeclared(property, context) && !isDebuggerContext(context)) return false;
// Delegated and extension properties have no backing fields
if (isDelegated || property.getReceiverParameter() != null) return false;
@@ -279,6 +280,11 @@ public class JvmCodegenUtil {
return property.getVisibility() == Visibilities.PRIVATE || accessor.getModality() == FINAL;
}
private static boolean isDebuggerContext(@NotNull MethodContext context) {
JetFile file = DescriptorToSourceUtils.getContainingFile(context.getContextDescriptor());
return file != null && CodeFragmentUtilPackage.getSkipVisibilityCheck(file);
}
@NotNull
public static ImplementationBodyCodegen getParentBodyCodegen(@Nullable MemberCodegen<?> classBodyCodegen) {
assert classBodyCodegen != null && classBodyCodegen.getParentCodegen() instanceof ImplementationBodyCodegen