[Analysis API FIR] fix call resolution of non-resolvable elements
This commit is contained in:
+2
-2
@@ -145,7 +145,7 @@ internal class KtFe10CallResolver(
|
||||
get() = analysisSession.token
|
||||
|
||||
override fun resolveCall(psi: KtElement): KtCallInfo? = with(analysisContext.analyze(psi, AnalysisMode.PARTIAL_WITH_DIAGNOSTICS)) {
|
||||
if (psi.isNotResolvable()) return null
|
||||
if (!canBeResolvedAsCall(psi)) return null
|
||||
|
||||
val parentBinaryExpression = psi.parentOfType<KtBinaryExpression>()
|
||||
val lhs = KtPsiUtil.deparenthesize(parentBinaryExpression?.left)
|
||||
@@ -177,7 +177,7 @@ internal class KtFe10CallResolver(
|
||||
|
||||
override fun collectCallCandidates(psi: KtElement): List<KtCallCandidateInfo> =
|
||||
with(analysisContext.analyze(psi, AnalysisMode.PARTIAL_WITH_DIAGNOSTICS)) {
|
||||
if (psi.isNotResolvable()) return emptyList()
|
||||
if (!canBeResolvedAsCall(psi)) return emptyList()
|
||||
|
||||
val resolvedKtCallInfo = resolveCall(psi)
|
||||
val bestCandidateDescriptors =
|
||||
|
||||
+28
@@ -854,6 +854,34 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class NonCalls {
|
||||
@Test
|
||||
public void testAllFilesPresentInNonCalls() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ifExpression.kt")
|
||||
public void testIfExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("literalExpression.kt")
|
||||
public void testLiteralExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenExpression.kt")
|
||||
public void testWhenExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/withTestCompilerPluginEnabled")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+13
-11
@@ -86,18 +86,20 @@ internal class KtFirCallResolver(
|
||||
result
|
||||
}
|
||||
|
||||
override fun resolveCall(psi: KtElement): KtCallInfo? = wrapError(psi) {
|
||||
val ktCallInfos = getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
|
||||
listOfNotNull(
|
||||
toKtCallInfo(
|
||||
psiToResolve,
|
||||
resolveCalleeExpressionOfFunctionCall,
|
||||
resolveFragmentOfCall
|
||||
override fun resolveCall(psi: KtElement): KtCallInfo? {
|
||||
return wrapError(psi) {
|
||||
val ktCallInfos = getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
|
||||
listOfNotNull(
|
||||
toKtCallInfo(
|
||||
psiToResolve,
|
||||
resolveCalleeExpressionOfFunctionCall,
|
||||
resolveFragmentOfCall
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
check(ktCallInfos.size <= 1) { "Should only return 1 KtCallInfo" }
|
||||
ktCallInfos.singleOrNull()
|
||||
}
|
||||
check(ktCallInfos.size <= 1) { "Should only return 1 KtCallInfo" }
|
||||
ktCallInfos.singleOrNull()
|
||||
}
|
||||
|
||||
private inline fun <T> getCallInfo(
|
||||
@@ -108,7 +110,7 @@ internal class KtFirCallResolver(
|
||||
resolveFragmentOfCall: Boolean
|
||||
) -> List<T>
|
||||
): List<T> {
|
||||
if (psi.isNotResolvable()) return emptyList()
|
||||
if (!canBeResolvedAsCall(psi)) return emptyList()
|
||||
|
||||
val containingCallExpressionForCalleeExpression = psi.getContainingCallExpressionForCalleeExpression()
|
||||
val containingBinaryExpressionForLhs = psi.getContainingBinaryExpressionForIncompleteLhs()
|
||||
|
||||
+28
@@ -854,6 +854,34 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class NonCalls {
|
||||
@Test
|
||||
public void testAllFilesPresentInNonCalls() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ifExpression.kt")
|
||||
public void testIfExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("literalExpression.kt")
|
||||
public void testLiteralExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenExpression.kt")
|
||||
public void testWhenExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/withTestCompilerPluginEnabled")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+12
-10
@@ -45,17 +45,19 @@ abstract class AbstractKtCallResolver : KtCallResolver() {
|
||||
return KtPsiUtil.deparenthesize(safeQualifiedExpression.receiverExpression) == KtPsiUtil.deparenthesize(this)
|
||||
}
|
||||
|
||||
protected fun canBeResolvedAsCall(ktElement: KtElement): Boolean = when (ktElement) {
|
||||
is KtBinaryExpression -> ktElement.operationToken !in nonCallBinaryOperator
|
||||
is KtOperationReferenceExpression -> ktElement.operationSignTokenType !in nonCallBinaryOperator
|
||||
is KtCallElement -> true
|
||||
is KtConstructorCalleeExpression -> true
|
||||
is KtDotQualifiedExpression -> true
|
||||
is KtNameReferenceExpression -> true
|
||||
is KtOperationExpression -> true
|
||||
is KtArrayAccessExpression -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
protected companion object {
|
||||
private val nonCallBinaryOperator: Set<KtSingleValueToken> = setOf(KtTokens.ELVIS, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ)
|
||||
|
||||
/**
|
||||
* We don't want to resolve the operators from the [AbstractKtCallResolver.nonCallBinaryOperator] list, because it's either
|
||||
* not possible or not desirable.
|
||||
*/
|
||||
fun KtElement.isNotResolvable(): Boolean {
|
||||
return this is KtBinaryExpression && operationToken in nonCallBinaryOperator ||
|
||||
this is KtOperationReferenceExpression && operationSignTokenType in nonCallBinaryOperator
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+28
@@ -853,4 +853,32 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/assignments/insidePlusAssignTarget.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class NonCalls {
|
||||
@Test
|
||||
public void testAllFilesPresentInNonCalls() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true, "withTestCompilerPluginEnabled");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ifExpression.kt")
|
||||
public void testIfExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("literalExpression.kt")
|
||||
public void testLiteralExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenExpression.kt")
|
||||
public void testWhenExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val x = <expr>if (true) 1 else 2</expr>
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
null
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val x = <expr>1</expr>
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
null
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
val x = <expr>when (true) { else -> 2 }</expr>
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
null
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
KtErrorCallInfo:
|
||||
candidateCalls = []
|
||||
diagnostic = ERROR<OTHER_ERROR: Unknown (other) error>
|
||||
diagnostic = ERROR<null: Erroneous delegated constructor call>
|
||||
Reference in New Issue
Block a user