Refactor CodegenContext#accessibleDescriptorIfNeeded

This commit is contained in:
Alexander Udalov
2015-09-07 15:36:54 +03:00
parent dbaf01feed
commit 8a5e83b947
5 changed files with 38 additions and 66 deletions
@@ -2007,7 +2007,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
JetExpression r = getReceiverForSelector(expression); JetExpression r = getReceiverForSelector(expression);
boolean isSuper = r instanceof JetSuperExpression; boolean isSuper = r instanceof JetSuperExpression;
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor); propertyDescriptor = context.accessibleDescriptor(propertyDescriptor);
if (directToField) { if (directToField) {
receiver = StackValue.receiverWithoutReceiverArgument(receiver); receiver = StackValue.receiverWithoutReceiverArgument(receiver);
@@ -2196,7 +2196,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
} }
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor); propertyDescriptor = context.accessibleDescriptor(propertyDescriptor);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null) { if (getter != null) {
@@ -2321,11 +2321,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}); });
} }
@NotNull
private PropertyDescriptor accessiblePropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
return context.accessiblePropertyDescriptor(propertyDescriptor);
}
@NotNull @NotNull
private FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<?> resolvedCall) { private FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<?> resolvedCall) {
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor(); FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
@@ -2334,7 +2329,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
descriptor = originalIfSamAdapter; descriptor = originalIfSamAdapter;
} }
// $default method is not private, so you need no accessor to call it // $default method is not private, so you need no accessor to call it
return usesDefaultArguments(resolvedCall) ? descriptor : context.accessibleFunctionDescriptor(descriptor); return usesDefaultArguments(resolvedCall) ? descriptor : context.accessibleDescriptor(descriptor);
} }
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) { private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
@@ -210,7 +210,7 @@ public class FunctionCodegen {
mv.visitCode(); mv.visitCode();
FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor); FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
JvmMethodSignature jvmMethodSignature = JvmMethodSignature jvmMethodSignature =
typeMapper.mapSignature(memberCodegen.getContext().accessibleFunctionDescriptor(staticFunctionDescriptor)); typeMapper.mapSignature(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration()); Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName()); generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
} }
@@ -1074,7 +1074,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) { private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
ExpressionCodegen codegen = createOrGetClInitCodegen(); ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor constructor = context.accessibleFunctionDescriptor(KotlinPackage.single(companionObject.getConstructors())); FunctionDescriptor constructor =
(FunctionDescriptor) context.accessibleDescriptor(KotlinPackage.single(companionObject.getConstructors()));
generateMethodCallTo(constructor, null, codegen.v); generateMethodCallTo(constructor, null, codegen.v);
codegen.v.dup(); codegen.v.dup();
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject)); StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
@@ -67,7 +67,7 @@ class PlatformStaticGenerator(
} }
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod( val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
codegen.getContext().accessibleFunctionDescriptor(descriptor), codegen.getContext().accessibleDescriptor(descriptor),
false, false,
codegen.getContext() codegen.getContext()
) )
@@ -34,6 +34,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.*; import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag; import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.kotlin.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
@@ -223,21 +224,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
@NotNull @NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor) { public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor) {
return getAccessor(descriptor, false, null); return getAccessor(descriptor, false, null);
} }
@SuppressWarnings("unchecked")
@NotNull @NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType) { public <D extends CallableMemberDescriptor> D getAccessor(
@NotNull D descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType
) {
if (accessors == null) { if (accessors == null) {
accessors = new LinkedHashMap<DeclarationDescriptor, DeclarationDescriptor>(); accessors = new LinkedHashMap<DeclarationDescriptor, DeclarationDescriptor>();
} }
descriptor = descriptor.getOriginal(); descriptor = (D) descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor); DeclarationDescriptor accessor = accessors.get(descriptor);
if (accessor != null) { if (accessor != null) {
assert !isForBackingFieldInOuterClass || assert !isForBackingFieldInOuterClass ||
accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context"; accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context";
return accessor; return (D) accessor;
} }
int accessorIndex = accessors.size(); int accessorIndex = accessors.size();
@@ -251,7 +255,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (isForBackingFieldInOuterClass) { if (isForBackingFieldInOuterClass) {
accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor, accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor,
accessorIndex, delegateType); accessorIndex, delegateType);
} else { }
else {
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessorIndex); accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessorIndex);
} }
} }
@@ -259,7 +264,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor); throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor);
} }
accessors.put(descriptor, accessor); accessors.put(descriptor, accessor);
return accessor; return (D) accessor;
} }
@Nullable @Nullable
@@ -311,34 +316,23 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
@NotNull @NotNull
public PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) { public <D extends CallableMemberDescriptor> D accessibleDescriptor(D descriptor) {
return (PropertyDescriptor) accessibleDescriptorIfNeeded(propertyDescriptor, true); DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
} if (!hasThisDescriptor() || enclosing == getThisDescriptor() ||
enclosing == getClassOrPackageParentContext().getContextDescriptor()) {
@NotNull return descriptor;
public FunctionDescriptor accessibleFunctionDescriptor(FunctionDescriptor fd) {
return (FunctionDescriptor) accessibleDescriptorIfNeeded(fd, true);
}
public void recordSyntheticAccessorIfNeeded(@NotNull FunctionDescriptor fd, @NotNull BindingContext bindingContext) {
if (fd instanceof ConstructorDescriptor || needSyntheticAccessorInBindingTrace(fd, bindingContext)) {
accessibleDescriptorIfNeeded(fd, false);
} }
return accessibleDescriptorIfNeeded(descriptor);
} }
public void recordSyntheticAccessorIfNeeded(@NotNull PropertyDescriptor propertyDescriptor, @NotNull BindingContext typeMapper) { public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
if (needSyntheticAccessorInBindingTrace(propertyDescriptor, typeMapper)) { if (hasThisDescriptor() &&
accessibleDescriptorIfNeeded(propertyDescriptor, false); (descriptor instanceof ConstructorDescriptor || Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor)))) {
accessibleDescriptorIfNeeded(descriptor);
} }
} }
private static boolean needSyntheticAccessorInBindingTrace(
@NotNull CallableMemberDescriptor descriptor,
@NotNull BindingContext bindingContext
) {
return Boolean.TRUE.equals(bindingContext.get(BindingContext.NEED_SYNTHETIC_ACCESSOR, descriptor));
}
private static int getAccessFlags(@NotNull CallableMemberDescriptor descriptor) { private static int getAccessFlags(@NotNull CallableMemberDescriptor descriptor) {
int flag = getVisibilityAccessFlag(descriptor); int flag = getVisibilityAccessFlag(descriptor);
if (descriptor instanceof PropertyDescriptor) { if (descriptor instanceof PropertyDescriptor) {
@@ -353,39 +347,21 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return flag; return flag;
} }
@SuppressWarnings("unchecked")
@NotNull @NotNull
private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) { private <D extends CallableMemberDescriptor> D accessibleDescriptorIfNeeded(@NotNull D descriptor) {
CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor); CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor);
int flag = getAccessFlags(unwrappedDescriptor); int flag = getAccessFlags(unwrappedDescriptor);
if ((flag & ACC_PRIVATE) == 0 && (flag & ACC_PROTECTED) == 0) { if ((flag & ACC_PRIVATE) == 0 && (flag & ACC_PROTECTED) == 0) {
return descriptor; return descriptor;
} }
CodegenContext descriptorContext = null; DeclarationDescriptor enclosed = descriptor.getContainingDeclaration();
if (!fromOutsideContext || getClassOrPackageParentContext().getContextDescriptor() != descriptor.getContainingDeclaration()) { CodegenContext descriptorContext = findParentContextWithDescriptor(enclosed);
DeclarationDescriptor enclosed = descriptor.getContainingDeclaration(); if (descriptorContext == null && DescriptorUtils.isCompanionObject(enclosed)) {
boolean isCompanionObjectMember = DescriptorUtils.isCompanionObject(enclosed); CodegenContext classContext = findParentContextWithDescriptor(enclosed.getContainingDeclaration());
//go upper if (classContext instanceof ClassContext) {
if (hasThisDescriptor() && (enclosed != getThisDescriptor() || !fromOutsideContext)) { descriptorContext = ((ClassContext) classContext).getCompanionObjectContext();
CodegenContext currentContext = this;
while (currentContext != null) {
if (currentContext.getContextDescriptor() == enclosed) {
descriptorContext = currentContext;
break;
}
//accessors for private members in companion object for call from class
if (isCompanionObjectMember && currentContext instanceof ClassContext) {
ClassContext classContext = (ClassContext) currentContext;
CodegenContext companionObjectContext = classContext.getCompanionObjectContext();
if (companionObjectContext != null && companionObjectContext.getContextDescriptor() == enclosed) {
descriptorContext = companionObjectContext;
break;
}
}
currentContext = currentContext.getParentContext();
}
} }
} }
@@ -406,7 +382,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
} }
return (MemberDescriptor) descriptorContext.getAccessor(descriptor); return (D) descriptorContext.getAccessor(descriptor);
} }
private void addChild(@NotNull CodegenContext child) { private void addChild(@NotNull CodegenContext child) {