[Analysis API] Fix exceptions around type parameters being treated as callables

- `toResolvedCallableSymbol`: cast defensively because
  the resolved symbol might not be a callable symbol.
- `toKtCallInfo`: Check that the resolved symbol is actually callable.

^KTIJ-23003 fixed
This commit is contained in:
Marco Pennekamp
2022-11-11 13:49:55 +01:00
committed by teamcity
parent 170c19d293
commit c5e5140c08
11 changed files with 67 additions and 5 deletions
@@ -898,6 +898,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A
public void testGetterAssignment() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/typeParameterAsValue.kt");
}
}
@Nested
@@ -168,10 +168,20 @@ internal class KtFirCallResolver(
return when (this) {
is FirResolvable -> {
when (val calleeReference = calleeReference) {
is FirResolvedNamedReference -> {
val call = createKtCall(psi, this, null, resolveFragmentOfCall)
?: errorWithFirSpecificEntries("expect `createKtCall` to succeed for resolvable case", fir = this, psi = psi)
KtSuccessCallInfo(call)
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
// `calleeReference.resolvedSymbol` isn't guaranteed to be callable. For example, function type parameters used in
// expression positions (e.g. `T` in `println(T)`) are parsed as `KtSimpleNameExpression` and built into
// `FirPropertyAccessExpression` (which is `FirResolvable`).
is FirCallableSymbol<*> -> {
val call = createKtCall(psi, this, null, resolveFragmentOfCall)
?: errorWithFirSpecificEntries(
"expect `createKtCall` to succeed for resolvable case with callable symbol",
fir = this,
psi = psi
)
KtSuccessCallInfo(call)
}
else -> null
}
is FirErrorNamedReference -> {
val diagnostic = calleeReference.diagnostic
@@ -898,6 +898,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
public void testGetterAssignment() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/typeParameterAsValue.kt");
}
}
@Nested
@@ -127,6 +127,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/importOptimizer/analyseImports/referencesWithErrors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("unusedTypeHiddenByTypeParameter_invalidAsArgument.kt")
public void testUnusedTypeHiddenByTypeParameter_invalidAsArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/referencesWithErrors/unusedTypeHiddenByTypeParameter_invalidAsArgument.kt");
}
@Test
@TestMetadata("usedConstructor_invalidArguments.kt")
public void testUsedConstructor_invalidArguments() throws Exception {
@@ -898,6 +898,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext
public void testGetterAssignment() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/typeParameterAsValue.kt");
}
}
@Nested
@@ -127,6 +127,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/importOptimizer/analyseImports/referencesWithErrors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("unusedTypeHiddenByTypeParameter_invalidAsArgument.kt")
public void testUnusedTypeHiddenByTypeParameter_invalidAsArgument() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/referencesWithErrors/unusedTypeHiddenByTypeParameter_invalidAsArgument.kt");
}
@Test
@TestMetadata("usedConstructor_invalidArguments.kt")
public void testUsedConstructor_invalidArguments() throws Exception {
@@ -0,0 +1,5 @@
// See: KTIJ-23003 (KotlinExceptionWithAttachments)
fun <T> test(x: Any) {
println(<expr>T</expr>)
}
@@ -0,0 +1,15 @@
// See: KTIJ-23003 (ClassCastException)
// FILE: main.kt
package test
import dependency.T
fun <T> usage() {
println(T)
}
// FILE: dependency.kt
package dependency
class T(i: Int)
@@ -74,7 +74,7 @@ fun FirExpression.toReference(): FirReference? {
}
fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
return toResolvedCallableReference()?.resolvedSymbol as FirCallableSymbol<*>?
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>?
}
fun FirReference.toResolvedCallableSymbol(): FirCallableSymbol<*>? {