Check noinline annotation on non-local return processing

This commit is contained in:
Michael Bogdanov
2014-09-16 15:33:14 +04:00
parent b763aa9995
commit a735d67e86
3 changed files with 43 additions and 18 deletions
@@ -46,24 +46,7 @@ public class InlineDescriptorUtils {
while (containingFunction instanceof JetFunctionLiteral && fromFunction != containingFunctionDescriptor) {
//JetFunctionLiteralExpression
containingFunction = containingFunction.getParent();
boolean allowsNonLocalReturns = false;
JetExpression call = JetPsiUtil.getParentCallIfPresent((JetFunctionLiteralExpression) containingFunction);
if (call != null) {
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext);
CallableDescriptor resultingDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
if (resultingDescriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) resultingDescriptor).getInlineStrategy().isInline()) {
ValueArgument argument = CallUtilPackage.getValueArgumentForExpression(
resolvedCall.getCall(), (JetFunctionLiteralExpression) containingFunction);
if (argument != null) {
ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument);
if (mapping instanceof ArgumentMatch) {
allowsNonLocalReturns = allowsNonLocalReturns(((ArgumentMatch) mapping).getValueParameter());
}
}
}
}
if (!allowsNonLocalReturns) {
if (!isInlineLambda((JetFunctionLiteralExpression) containingFunction, bindingContext, true)) {
return false;
}
@@ -77,6 +60,32 @@ public class InlineDescriptorUtils {
return fromFunction == containingFunctionDescriptor;
}
public static boolean isInlineLambda(
@NotNull JetFunctionLiteralExpression lambdaExpression,
@NotNull BindingContext bindingContext,
boolean checkNonLocalReturn
) {
JetExpression call = JetPsiUtil.getParentCallIfPresent(lambdaExpression);
if (call != null) {
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext);
CallableDescriptor resultingDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
if (resultingDescriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) resultingDescriptor).getInlineStrategy().isInline()) {
ValueArgument argument = CallUtilPackage.getValueArgumentForExpression(resolvedCall.getCall(), lambdaExpression);
if (argument != null) {
ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument);
if (mapping instanceof ArgumentMatch) {
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
if (!InlineUtil.hasNoinlineAnnotation(parameter)) {
return !checkNonLocalReturn || allowsNonLocalReturns(parameter);
}
}
}
}
}
return false;
}
@Nullable
public static DeclarationDescriptor getContainingClassOrFunctionDescriptor(@NotNull DeclarationDescriptor descriptor, boolean strict) {
DeclarationDescriptor currentDescriptor = strict ? descriptor.getContainingDeclaration() : descriptor;