diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
index d4c73387c58..bc6fc1ff96e 100644
--- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
+++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionInfoProvider/Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
@@ -958,6 +958,18 @@ public class Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated ex
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/functionLiteralExtensionReceiverType.kt");
}
+ @Test
+ @TestMetadata("function_body_with_if.kt")
+ public void testFunction_body_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt");
+ }
+
+ @Test
+ @TestMetadata("function_equal_block_with_if.kt")
+ public void testFunction_equal_block_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt");
+ }
+
@Test
@TestMetadata("ifBranches_unused.kt")
public void testIfBranches_unused() throws Exception {
@@ -1510,12 +1522,24 @@ public class Fe10IdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated ex
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_implicit_unit.kt");
}
+ @Test
+ @TestMetadata("return_inside_if.kt")
+ public void testReturn_inside_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt");
+ }
+
@Test
@TestMetadata("return_value.kt")
public void testReturn_value() throws Exception {
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_value.kt");
}
+ @Test
+ @TestMetadata("return_with_if.kt")
+ public void testReturn_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt");
+ }
+
@Test
@TestMetadata("run_block.kt")
public void testRun_block() throws Exception {
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionInfoProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionInfoProvider.kt
index de05b88e3d3..9f7d8bc8f8a 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionInfoProvider.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionInfoProvider.kt
@@ -209,8 +209,6 @@ internal class KtFirExpressionInfoProvider(
is KtFunctionLiteral ->
parent.bodyBlockExpression == child && !returnsUnit(parent)
- // Named functions do not use their bodies if the function itself returns unit
- // UNLESS it's an expression body/lambda of type Unit.
/** See [doesNamedFunctionUseBody] */
is KtNamedFunction ->
doesNamedFunctionUseBody(parent, child)
@@ -402,23 +400,26 @@ private fun doesPropertyAccessorUseBody(propertyAccessor: KtPropertyAccessor, bo
}
/**
- * Named functions do not consider their bodies used if the function itself
- * returns Unit UNLESS the function body is an expression body and the body is
- * of type Unit.
+ * Returns whether the function uses its body as an expression (i.e., the function uses the result value of the expression) or not.
+ *
+ * Named functions do not consider their bodies used if
+ * - the function body is a block e.g., `fun foo(): Int { return bar }` or
+ * - the function itself returns Unit
*/
-private fun doesNamedFunctionUseBody(namedFunction: KtNamedFunction, body: PsiElement): Boolean =
- when {
- !returnsUnit(namedFunction) ->
- true
- namedFunction.bodyBlockExpression == body ->
- false
- namedFunction.bodyExpression == body ->
- analyze(namedFunction) {
- (body as KtExpression).getKtType()?.isUnit == true
- }
- else ->
- false
- }
+private fun doesNamedFunctionUseBody(namedFunction: KtNamedFunction, body: PsiElement): Boolean = when {
+ // The body is a block expression e.g., fun foo(): Int { return bar }
+ namedFunction.bodyBlockExpression == body ->
+ false
+ // Note that `namedFunction.hasBlockBody() == false` means the function definition uses `=` e.g., fun foo() = bar
+ !returnsUnit(namedFunction) ->
+ true
+ namedFunction.bodyExpression == body ->
+ analyze(namedFunction) {
+ (body as KtExpression).getKtType()?.isUnit == true
+ }
+ else ->
+ false
+}
private fun KtAnalysisSession.isSimpleVariableAccessCall(reference: KtReferenceExpression): Boolean =
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
index 2f1ed276fd9..7d43c7c7c8f 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
@@ -958,6 +958,18 @@ public class FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/functionLiteralExtensionReceiverType.kt");
}
+ @Test
+ @TestMetadata("function_body_with_if.kt")
+ public void testFunction_body_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt");
+ }
+
+ @Test
+ @TestMetadata("function_equal_block_with_if.kt")
+ public void testFunction_equal_block_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt");
+ }
+
@Test
@TestMetadata("ifBranches_unused.kt")
public void testIfBranches_unused() throws Exception {
@@ -1510,12 +1522,24 @@ public class FirIdeDependentAnalysisSourceModuleIsUsedAsExpressionTestGenerated
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_implicit_unit.kt");
}
+ @Test
+ @TestMetadata("return_inside_if.kt")
+ public void testReturn_inside_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt");
+ }
+
@Test
@TestMetadata("return_value.kt")
public void testReturn_value() throws Exception {
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_value.kt");
}
+ @Test
+ @TestMetadata("return_with_if.kt")
+ public void testReturn_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt");
+ }
+
@Test
@TestMetadata("run_block.kt")
public void testRun_block() throws Exception {
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
index 936af657b40..94d5ad78b49 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionInfoProvider/FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
@@ -958,6 +958,18 @@ public class FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated ext
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/functionLiteralExtensionReceiverType.kt");
}
+ @Test
+ @TestMetadata("function_body_with_if.kt")
+ public void testFunction_body_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt");
+ }
+
+ @Test
+ @TestMetadata("function_equal_block_with_if.kt")
+ public void testFunction_equal_block_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt");
+ }
+
@Test
@TestMetadata("ifBranches_unused.kt")
public void testIfBranches_unused() throws Exception {
@@ -1510,12 +1522,24 @@ public class FirIdeNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated ext
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_implicit_unit.kt");
}
+ @Test
+ @TestMetadata("return_inside_if.kt")
+ public void testReturn_inside_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt");
+ }
+
@Test
@TestMetadata("return_value.kt")
public void testReturn_value() throws Exception {
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_value.kt");
}
+ @Test
+ @TestMetadata("return_with_if.kt")
+ public void testReturn_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt");
+ }
+
@Test
@TestMetadata("run_block.kt")
public void testRun_block() throws Exception {
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
index 1970b25700f..66a462872e1 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionInfoProvider/FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenerated.java
@@ -958,6 +958,18 @@ public class FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenera
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/functionLiteralExtensionReceiverType.kt");
}
+ @Test
+ @TestMetadata("function_body_with_if.kt")
+ public void testFunction_body_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt");
+ }
+
+ @Test
+ @TestMetadata("function_equal_block_with_if.kt")
+ public void testFunction_equal_block_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt");
+ }
+
@Test
@TestMetadata("ifBranches_unused.kt")
public void testIfBranches_unused() throws Exception {
@@ -1510,12 +1522,24 @@ public class FirStandaloneNormalAnalysisSourceModuleIsUsedAsExpressionTestGenera
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_implicit_unit.kt");
}
+ @Test
+ @TestMetadata("return_inside_if.kt")
+ public void testReturn_inside_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt");
+ }
+
@Test
@TestMetadata("return_value.kt")
public void testReturn_value() throws Exception {
runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_value.kt");
}
+ @Test
+ @TestMetadata("return_with_if.kt")
+ public void testReturn_with_if() throws Exception {
+ runTest("analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt");
+ }
+
@Test
@TestMetadata("run_block.kt")
public void testRun_block() throws Exception {
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt
new file mode 100644
index 00000000000..3aa66292035
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.kt
@@ -0,0 +1,5 @@
+fun test(n: Int) =
+ if (n == 1)
+ "one"
+ else
+ "two"
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.txt
new file mode 100644
index 00000000000..7618937d187
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_body_with_if.txt
@@ -0,0 +1,6 @@
+expression: IF
+text: if (n == 1)
+ "one"
+ else
+ "two"
+isUsedAsExpression: true
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt
new file mode 100644
index 00000000000..1eb5f326c05
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.kt
@@ -0,0 +1,6 @@
+fun test(n: Int) = {
+ if (n == 1)
+ "one"
+ else
+ "two"
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.txt
new file mode 100644
index 00000000000..7618937d187
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/function_equal_block_with_if.txt
@@ -0,0 +1,6 @@
+expression: IF
+text: if (n == 1)
+ "one"
+ else
+ "two"
+isUsedAsExpression: true
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt
new file mode 100644
index 00000000000..ec7e387c332
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.kt
@@ -0,0 +1,6 @@
+fun test(n: Int): String {
+ if (n == 1)
+ return "one"
+ else
+ return "two"
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.txt
new file mode 100644
index 00000000000..f5432371559
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_inside_if.txt
@@ -0,0 +1,3 @@
+expression: RETURN
+text: return "one"
+isUsedAsExpression: false
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt
new file mode 100644
index 00000000000..8217d961b73
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.kt
@@ -0,0 +1,6 @@
+fun test(n: Int): String {
+ if (n == 1)
+ return "one"
+ else
+ return "two"
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.txt b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.txt
new file mode 100644
index 00000000000..dc0fde42ce5
--- /dev/null
+++ b/analysis/analysis-api/testData/components/expressionInfoProvider/isUsedAsExpression/return_with_if.txt
@@ -0,0 +1,6 @@
+expression: IF
+text: if (n == 1)
+ return "one"
+ else
+ return "two"
+isUsedAsExpression: false