Mark array constructors with 'inline'

To allow non-local returns from lambdas passed to them
This commit is contained in:
Alexander Udalov
2016-01-27 19:52:39 +03:00
parent 70e847b794
commit a02d1b75b8
9 changed files with 62 additions and 31 deletions
@@ -111,22 +111,22 @@ public class InlineUtil {
if (!canBeInlineArgument(argument)) return null;
KtExpression call = KtPsiUtil.getParentCallIfPresent(argument);
if (call != null) {
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(call, bindingContext);
if (resolvedCall != null && isInline(resolvedCall.getResultingDescriptor())) {
ValueArgument valueArgument = CallUtilKt.getValueArgumentForExpression(resolvedCall.getCall(), argument);
if (valueArgument != null) {
ArgumentMapping mapping = resolvedCall.getArgumentMapping(valueArgument);
if (mapping instanceof ArgumentMatch) {
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
if (isInlineLambdaParameter(parameter)) {
return parameter;
}
}
}
}
}
return null;
if (call == null) return null;
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(call, bindingContext);
if (resolvedCall == null) return null;
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
if (!isInline(descriptor) && !isArrayConstructorWithLambda(descriptor)) return null;
ValueArgument valueArgument = CallUtilKt.getValueArgumentForExpression(resolvedCall.getCall(), argument);
if (valueArgument == null) return null;
ArgumentMapping mapping = resolvedCall.getArgumentMapping(valueArgument);
if (!(mapping instanceof ArgumentMatch)) return null;
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
return isInlineLambdaParameter(parameter) ? parameter : null;
}
public static boolean canBeInlineArgument(@Nullable PsiElement functionalExpression) {
+1 -1
View File
@@ -22,7 +22,7 @@ public open class Any {
}
public final class Array</*0*/ T> : kotlin.Cloneable {
/*primary*/ public constructor Array</*0*/ T>(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> T)
public constructor Array</*0*/ T>(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> T)
public final val size: kotlin.Int
public final fun <get-size>(): kotlin.Int
public open override /*1*/ fun clone(): kotlin.Array<T>
@@ -0,0 +1,21 @@
fun testArray() {
Array<String>(5) { i ->
if (i == 3) return
i.toString()
}
throw AssertionError()
}
fun testIntArray() {
IntArray(5) { i ->
if (i == 3) return
i
}
throw AssertionError()
}
fun box(): String {
testArray()
testIntArray()
return "OK"
}
@@ -1,4 +1,4 @@
inline fun <reified T> jaggedArray(crossinline x: (Int, Int) -> T): Array<Array<T>> = Array(1) { i ->
inline fun <reified T> jaggedArray(x: (Int, Int) -> T): Array<Array<T>> = Array(1) { i ->
Array(1) { j -> x(i, j) }
}
@@ -1,4 +1,4 @@
inline fun <reified T> jaggedArray(crossinline x: (Int, Int, Int) -> T): Array<Array<Array<T>>> = Array(1) { i ->
inline fun <reified T> jaggedArray(x: (Int, Int, Int) -> T): Array<Array<Array<T>>> = Array(1) { i ->
Array(1) {
j -> Array(1) { k -> x(i, j, k) }
}
@@ -286,6 +286,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("nonLocalReturnArrayConstructor.kt")
public void testNonLocalReturnArrayConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/arrays/nonLocalReturnArrayConstructor.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("nonNullArray.kt")
public void testNonNullArray() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/arrays/nonNullArray.kt");