From eaeb976903ce4c815177b662836ea9b40b3728cf Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 17 Jul 2014 16:40:59 +0400 Subject: [PATCH] Access private class property via field in Evaluate Expression --- .../jet/codegen/ExpressionCodegen.java | 5 ++--- .../jetbrains/jet/codegen/JvmCodegenUtil.java | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index dd396ecc380..4139c35a327 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1836,7 +1836,6 @@ public class ExpressionCodegen extends JetVisitor 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 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 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 { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmCodegenUtil.java index 4f52a8d0523..a54094433fd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmCodegenUtil.java @@ -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