Access private class property via field in Evaluate Expression
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user