Make $default methods non-private, avoid generating accessors for them

#KT-5786 Fixed
This commit is contained in:
Alexander Udalov
2015-04-23 16:42:51 +03:00
parent dc05596ce0
commit 07c2442405
10 changed files with 132 additions and 19 deletions
@@ -2165,21 +2165,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitCallExpression(@NotNull JetCallExpression expression, StackValue receiver) {
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
CallableDescriptor funDescriptor = resolvedCall.getResultingDescriptor();
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
if (!(funDescriptor instanceof FunctionDescriptor)) {
throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor);
}
funDescriptor = accessibleFunctionDescriptor((FunctionDescriptor) funDescriptor);
if (funDescriptor instanceof ConstructorDescriptor) {
if (descriptor instanceof ConstructorDescriptor) {
return generateNewCall(expression, resolvedCall);
}
if (funDescriptor.getOriginal() instanceof SamConstructorDescriptor) {
if (descriptor.getOriginal() instanceof SamConstructorDescriptor) {
JetExpression argumentExpression = bindingContext.get(SAM_CONSTRUCTOR_TO_ARGUMENT, expression);
assert argumentExpression != null : "Argument expression is not saved for a SAM constructor: " + funDescriptor;
assert argumentExpression != null : "Argument expression is not saved for a SAM constructor: " + descriptor;
return genSamInterfaceValue(argumentExpression, this);
}
@@ -2233,13 +2227,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
@NotNull
private PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
private PropertyDescriptor accessiblePropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
return context.accessiblePropertyDescriptor(propertyDescriptor);
}
@NotNull
protected FunctionDescriptor accessibleFunctionDescriptor(FunctionDescriptor fd) {
return context.accessibleFunctionDescriptor(fd);
private FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<?> resolvedCall) {
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
// $default method is not private, so you need no accessor to call it
return usesDefaultArguments(resolvedCall) ? descriptor : context.accessibleFunctionDescriptor(descriptor);
}
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
if (valueArguments == null) return false;
for (ResolvedValueArgument argument : valueArguments) {
if (argument instanceof DefaultValueArgument) return true;
}
return false;
}
@NotNull
@@ -2253,7 +2260,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return invokeFunction(call, ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall(), receiver);
}
FunctionDescriptor fd = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
JetSuperExpression superCallExpression = getSuperCallExpression(call);
boolean superCall = superCallExpression != null;
@@ -2266,8 +2273,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
FunctionDescriptor accessibleFunctionDescriptor = accessibleFunctionDescriptor(fd);
Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall, resolvedCall);
Callable callable = resolveToCallable(fd, superCall, resolvedCall);
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
}
@@ -578,8 +578,12 @@ public class FunctionCodegen {
int flags = getVisibilityAccessFlag(functionDescriptor) |
getDeprecatedAccessFlag(functionDescriptor) |
ACC_SYNTHETIC |
(functionDescriptor instanceof ConstructorDescriptor ? 0 : ACC_STATIC);
ACC_SYNTHETIC;
if (!(functionDescriptor instanceof ConstructorDescriptor)) {
flags |= ACC_STATIC;
}
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
flags &= ~ACC_PRIVATE;
Method defaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, kind, owner);
@@ -1050,7 +1050,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor constructor = codegen.accessibleFunctionDescriptor(KotlinPackage.single(companionObject.getConstructors()));
FunctionDescriptor constructor = context.accessibleFunctionDescriptor(KotlinPackage.single(companionObject.getConstructors()));
generateMethodCallTo(constructor, codegen.v);
codegen.v.dup();
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));