Check noinline annotation on non-local return processing
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
fun main(args: Array<String>) {
|
||||
test {
|
||||
<!RETURN_NOT_ALLOWED!>return<!>
|
||||
}
|
||||
}
|
||||
|
||||
inline fun test(noinline lambda: () -> Unit) {
|
||||
lambda()
|
||||
}
|
||||
@@ -5667,6 +5667,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noInlineAnnotation.kt")
|
||||
public void testNoInlineAnnotation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineAnnotation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noInlineLambda.kt")
|
||||
public void testNoInlineLambda() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt");
|
||||
|
||||
Reference in New Issue
Block a user