Support functional expression in non-local returns

This commit is contained in:
Michael Bogdanov
2015-04-27 13:59:15 +03:00
parent 3a6e5ac78c
commit e0aa64b8d2
18 changed files with 210 additions and 81 deletions
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.calls.callUtil.isInlined
import org.jetbrains.kotlin.resolve.inline.InlineUtil
public class KotlinHighlightExitPointsHandlerFactory: HighlightUsagesHandlerFactoryBase() {
companion object {
@@ -85,8 +85,8 @@ private fun JetExpression.getRelevantFunction(): JetFunction? {
}
for (parent in parents(false)) {
when (parent) {
is JetFunctionLiteral -> if (!parent.isInlined((parent.getParent() as JetFunctionLiteralExpression).analyze())) return parent
is JetNamedFunction -> return parent
is JetFunctionLiteral,
is JetNamedFunction -> if (!InlineUtil.isInlineLambda(parent as JetFunction, parent.analyze(), false)) return parent
}
}
return null
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.isInlined
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
@@ -56,8 +56,8 @@ public class KotlinRecursiveCallLineMarkerProvider() : LineMarkerProvider {
private fun getEnclosingFunction(element: JetElement): JetNamedFunction? {
for (parent in element.parents(false)) {
when (parent) {
is JetFunctionLiteral -> if (!parent.isInlined(parent.analyze())) return null
is JetNamedFunction -> return parent
is JetFunctionLiteral -> if (!InlineUtil.isInlineLambda(parent, parent.analyze(), false)) return null
is JetNamedFunction -> if (!InlineUtil.isInlineLambda(parent, parent.analyze(), false)) return parent
is JetClassOrObject -> return null
}
}
@@ -0,0 +1,8 @@
fun test() {
fun f(a: Int) {
if (a > 0) {
<lineMarker descr="Recursive call">f</lineMarker>(a-1)
}
}
}
@@ -0,0 +1,14 @@
fun f(a: Int) {
run(fun () {
<lineMarker>f</lineMarker>(a - 1)
})
}
fun ff(a: Int) {
run1 {
ff(a - 1)
}
}
inline fun <T> run1(noinline f: () -> T): T { }
@@ -202,12 +202,24 @@ public class LineMarkersTestGenerated extends AbstractLineMarkersTest {
doTest(fileName);
}
@TestMetadata("functionalExpression.kt")
public void testFunctionalExpression() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/functionalExpression.kt");
doTest(fileName);
}
@TestMetadata("generic.kt")
public void testGeneric() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/generic.kt");
doTest(fileName);
}
@TestMetadata("inInlinedFunctionExpression.kt")
public void testInInlinedFunctionExpression() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedFunctionExpression.kt");
doTest(fileName);
}
@TestMetadata("inInlinedLambda.kt")
public void testInInlinedLambda() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/recursiveCall/inInlinedLambda.kt");