From 8a5e83b947732cacf308f32171e3c6844ccf3fc6 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 7 Sep 2015 15:36:54 +0300 Subject: [PATCH] Refactor CodegenContext#accessibleDescriptorIfNeeded --- .../kotlin/codegen/ExpressionCodegen.java | 11 +-- .../kotlin/codegen/FunctionCodegen.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 3 +- .../kotlin/codegen/PlatformStaticGenerator.kt | 2 +- .../codegen/context/CodegenContext.java | 86 +++++++------------ 5 files changed, 38 insertions(+), 66 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index d30093e9b44..09b2646ea8a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2007,7 +2007,7 @@ public class ExpressionCodegen extends JetVisitor 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 implem } } - propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor); + propertyDescriptor = context.accessibleDescriptor(propertyDescriptor); PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); if (getter != null) { @@ -2321,11 +2321,6 @@ public class ExpressionCodegen extends JetVisitor 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 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) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index c7a43fb7e79..adbf3bd4a0a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -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()); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 86226d8fba8..0e7cd2ece5b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -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)); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PlatformStaticGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PlatformStaticGenerator.kt index 40a9da250c3..920f09a8187 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PlatformStaticGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PlatformStaticGenerator.kt @@ -67,7 +67,7 @@ class PlatformStaticGenerator( } val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod( - codegen.getContext().accessibleFunctionDescriptor(descriptor), + codegen.getContext().accessibleDescriptor(descriptor), false, codegen.getContext() ) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index 976a6cd225b..481ec4bdd06 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -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 { } @NotNull - public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor) { + public 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 getAccessor( + @NotNull D descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType + ) { if (accessors == null) { accessors = new LinkedHashMap(); } - 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 { 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 { 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 { } @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 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 { return flag; } + @SuppressWarnings("unchecked") @NotNull - private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) { + private 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 { } } - return (MemberDescriptor) descriptorContext.getAccessor(descriptor); + return (D) descriptorContext.getAccessor(descriptor); } private void addChild(@NotNull CodegenContext child) {