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) {
|
while (containingFunction instanceof JetFunctionLiteral && fromFunction != containingFunctionDescriptor) {
|
||||||
//JetFunctionLiteralExpression
|
//JetFunctionLiteralExpression
|
||||||
containingFunction = containingFunction.getParent();
|
containingFunction = containingFunction.getParent();
|
||||||
boolean allowsNonLocalReturns = false;
|
if (!isInlineLambda((JetFunctionLiteralExpression) containingFunction, bindingContext, true)) {
|
||||||
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) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +60,32 @@ public class InlineDescriptorUtils {
|
|||||||
return fromFunction == containingFunctionDescriptor;
|
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
|
@Nullable
|
||||||
public static DeclarationDescriptor getContainingClassOrFunctionDescriptor(@NotNull DeclarationDescriptor descriptor, boolean strict) {
|
public static DeclarationDescriptor getContainingClassOrFunctionDescriptor(@NotNull DeclarationDescriptor descriptor, boolean strict) {
|
||||||
DeclarationDescriptor currentDescriptor = strict ? descriptor.getContainingDeclaration() : descriptor;
|
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);
|
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")
|
@TestMetadata("noInlineLambda.kt")
|
||||||
public void testNoInlineLambda() throws Exception {
|
public void testNoInlineLambda() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user