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;
JetExpression r = getReceiverForSelector(expression);
boolean isSuper = r instanceof JetSuperExpression;
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor);
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor);
if (directToField) {
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();
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
private FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<?> resolvedCall) {
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
@@ -2334,7 +2329,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
descriptor = originalIfSamAdapter;
}
// $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) {
@@ -210,7 +210,7 @@ public class FunctionCodegen {
mv.visitCode();
FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
JvmMethodSignature jvmMethodSignature =
typeMapper.mapSignature(memberCodegen.getContext().accessibleFunctionDescriptor(staticFunctionDescriptor));
typeMapper.mapSignature(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
}
@@ -1074,7 +1074,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
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);
codegen.v.dup();
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
@@ -67,7 +67,7 @@ class PlatformStaticGenerator(
}
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
codegen.getContext().accessibleFunctionDescriptor(descriptor),
codegen.getContext().accessibleDescriptor(descriptor),
false,
codegen.getContext()
)
@@ -34,6 +34,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
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_PROTECTED;
@@ -223,21 +224,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor) {
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor) {
return getAccessor(descriptor, false, null);
}
@SuppressWarnings("unchecked")
@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) {
accessors = new LinkedHashMap<DeclarationDescriptor, DeclarationDescriptor>();
}
descriptor = descriptor.getOriginal();
descriptor = (D) descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor);
if (accessor != null) {
assert !isForBackingFieldInOuterClass ||
accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context";
return accessor;
return (D) accessor;
}
int accessorIndex = accessors.size();
@@ -251,7 +255,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (isForBackingFieldInOuterClass) {
accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor,
accessorIndex, delegateType);
} else {
}
else {
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);
}
accessors.put(descriptor, accessor);
return accessor;
return (D) accessor;
}
@Nullable
@@ -311,34 +316,23 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
return (PropertyDescriptor) accessibleDescriptorIfNeeded(propertyDescriptor, true);
}
@NotNull
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);
public <D extends CallableMemberDescriptor> D accessibleDescriptor(D descriptor) {
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
if (!hasThisDescriptor() || enclosing == getThisDescriptor() ||
enclosing == getClassOrPackageParentContext().getContextDescriptor()) {
return descriptor;
}
return accessibleDescriptorIfNeeded(descriptor);
}
public void recordSyntheticAccessorIfNeeded(@NotNull PropertyDescriptor propertyDescriptor, @NotNull BindingContext typeMapper) {
if (needSyntheticAccessorInBindingTrace(propertyDescriptor, typeMapper)) {
accessibleDescriptorIfNeeded(propertyDescriptor, false);
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
if (hasThisDescriptor() &&
(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) {
int flag = getVisibilityAccessFlag(descriptor);
if (descriptor instanceof PropertyDescriptor) {
@@ -353,39 +347,21 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return flag;
}
@SuppressWarnings("unchecked")
@NotNull
private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) {
private <D extends CallableMemberDescriptor> D accessibleDescriptorIfNeeded(@NotNull D descriptor) {
CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor);
int flag = getAccessFlags(unwrappedDescriptor);
if ((flag & ACC_PRIVATE) == 0 && (flag & ACC_PROTECTED) == 0) {
return descriptor;
}
CodegenContext descriptorContext = null;
if (!fromOutsideContext || getClassOrPackageParentContext().getContextDescriptor() != descriptor.getContainingDeclaration()) {
DeclarationDescriptor enclosed = descriptor.getContainingDeclaration();
boolean isCompanionObjectMember = DescriptorUtils.isCompanionObject(enclosed);
//go upper
if (hasThisDescriptor() && (enclosed != getThisDescriptor() || !fromOutsideContext)) {
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();
}
DeclarationDescriptor enclosed = descriptor.getContainingDeclaration();
CodegenContext descriptorContext = findParentContextWithDescriptor(enclosed);
if (descriptorContext == null && DescriptorUtils.isCompanionObject(enclosed)) {
CodegenContext classContext = findParentContextWithDescriptor(enclosed.getContainingDeclaration());
if (classContext instanceof ClassContext) {
descriptorContext = ((ClassContext) classContext).getCompanionObjectContext();
}
}
@@ -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) {