KT UAST: bail out unexpected expression type

...if source PSI is not expression, e.g., constructor delegation call

^KTIJ-31633 fixed

GitOrigin-RevId: 8bfb67cf51262478736862cc05f529aee549714c
This commit is contained in:
Jinseong Jeon
2024-10-13 15:10:32 -07:00
committed by intellij-monorepo-bot
parent b9bddc11e6
commit 12e1eb0436
7 changed files with 61 additions and 11 deletions

View File

@@ -145,6 +145,11 @@ class KotlinUFunctionCallExpression(
}
override fun getExpressionType(): PsiType? {
if (sourcePsi !is KtExpression) {
// E.g., constructor(...) : this(...)
// [KtConstructorDelegationCall] is a subtype of [KtCallElement], but not [KtExpression]
return null
}
// KTIJ-17870: One-off handling for instantiation of local classes
if (classReference != null) {
// [classReference] is created only if this call expression is resolved to constructor.

View File

@@ -994,6 +994,43 @@ interface UastApiFixtureTestBase {
})
}
fun checkExpressionTypeForConstructorDelegationCall(myFixture: JavaCodeInsightTestFixture) {
// Regression test from KTIJ-31633
myFixture.configureByText(
"main.kt", """
class Constructors {
class ThisCall {
constructor() // (1)
constructor(i: Int) : this() // (2)
}
open class SuperCallToImplicit {
class C : SuperCallToImplicit {
constructor() : super() // (3)
}
}
open class SuperCallToExplicit {
constructor() // (4)
class C : SuperCallToExplicit {
constructor() : super() // (5)
}
}
}
""".trimIndent()
)
var count = 0
myFixture.file.toUElement()!!.accept(
object : AbstractUastVisitor() {
override fun visitCallExpression(node: UCallExpression): Boolean {
val t = node.getExpressionType()
TestCase.assertNull(node.sourcePsi?.text ?: "<no source PSI>", t)
count++
return super.visitCallExpression(node)
}
}
)
TestCase.assertEquals(5, count)
}
fun checkFlexibleFunctionalInterfaceType(myFixture: JavaCodeInsightTestFixture) {
myFixture.addClass(
"""

View File

@@ -126,6 +126,10 @@ class FirUastApiFixtureTest : KotlinLightCodeInsightFixtureTestCase(), UastApiFi
checkExpressionTypeForCallToInternalOperator(myFixture)
}
fun testExpressionTypeForConstructorDelegationCall() {
checkExpressionTypeForConstructorDelegationCall(myFixture)
}
fun testFlexibleFunctionalInterfaceType() {
checkFlexibleFunctionalInterfaceType(myFixture)
}

View File

@@ -58,7 +58,7 @@ UFile (package = ) [public final class CommentOwnersKt {...]
UParameter (name = t) [@org.jetbrains.annotations.NotNull var t: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()] : java.lang.Object
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()]
UIdentifier (Identifier ()) [UIdentifier (Identifier ())]
USimpleNameReferenceExpression (identifier = Object, resolvesTo = PsiClass: Object) [Object]
UClass (name = NestedClass) [public static final class NestedClass {...}]

View File

@@ -10,7 +10,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i.toString())] : A
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i.toString())]
UIdentifier (Identifier (this)) [UIdentifier (Identifier (this))]
USimpleNameReferenceExpression (identifier = A, resolvesTo = PsiClass: A) [A]
UQualifiedReferenceExpression [i.toString()] : java.lang.String
@@ -32,7 +32,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [AWithInit(i.toString())] : AWithInit
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [AWithInit(i.toString())]
UIdentifier (Identifier (this)) [UIdentifier (Identifier (this))]
USimpleNameReferenceExpression (identifier = AWithInit, resolvesTo = PsiClass: AWithInit) [AWithInit]
UQualifiedReferenceExpression [i.toString()] : java.lang.String
@@ -59,7 +59,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [AWith2Init(i.toString())] : AWith2Init
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [AWith2Init(i.toString())]
UIdentifier (Identifier (this)) [UIdentifier (Identifier (this))]
USimpleNameReferenceExpression (identifier = AWith2Init, resolvesTo = PsiClass: AWith2Init) [AWith2Init]
UQualifiedReferenceExpression [i.toString()] : java.lang.String
@@ -88,7 +88,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()] : java.lang.Object
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()]
UIdentifier (Identifier ()) [UIdentifier (Identifier ())]
USimpleNameReferenceExpression (identifier = Object, resolvesTo = PsiClass: Object) [Object]
UBinaryExpression (operator = =) [a = i.toString()] : @org.jetbrains.annotations.NotNull() kotlin.Unit
@@ -101,7 +101,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = s) [@org.jetbrains.annotations.NotNull var s: java.lang.String]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()] : java.lang.Object
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()]
UIdentifier (Identifier ()) [UIdentifier (Identifier ())]
USimpleNameReferenceExpression (identifier = Object, resolvesTo = PsiClass: Object) [Object]
UBinaryExpression (operator = =) [a = s] : @org.jetbrains.annotations.NotNull() kotlin.Unit
@@ -118,7 +118,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()] : java.lang.Object
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()]
UIdentifier (Identifier ()) [UIdentifier (Identifier ())]
USimpleNameReferenceExpression (identifier = Object, resolvesTo = PsiClass: Object) [Object]
UBlockExpression [{...}] : @org.jetbrains.annotations.NotNull() kotlin.Unit
@@ -134,7 +134,7 @@ UFile (package = ) [public final class A {...]
UParameter (name = s) [@org.jetbrains.annotations.NotNull var s: java.lang.String]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()] : java.lang.Object
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [Object()]
UIdentifier (Identifier ()) [UIdentifier (Identifier ())]
USimpleNameReferenceExpression (identifier = Object, resolvesTo = PsiClass: Object) [Object]
UBinaryExpression (operator = =) [a = s] : @org.jetbrains.annotations.NotNull() kotlin.Unit

View File

@@ -56,7 +56,7 @@ UFile (package = ) [public final class SuperCallsKt {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i.toString())] : A
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i.toString())]
UIdentifier (Identifier (this)) [UIdentifier (Identifier (this))]
USimpleNameReferenceExpression (identifier = A, resolvesTo = PsiClass: A) [A]
UQualifiedReferenceExpression [i.toString()] : java.lang.String
@@ -86,7 +86,7 @@ UFile (package = ) [public final class SuperCallsKt {...]
UParameter (name = p) [@org.jetbrains.annotations.NotNull var p: java.lang.String]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(p)] : A
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(p)]
UIdentifier (Identifier (super)) [UIdentifier (Identifier (super))]
USimpleNameReferenceExpression (identifier = A, resolvesTo = PsiClass: A) [A]
USimpleNameReferenceExpression (identifier = p) [p] : java.lang.String
@@ -94,7 +94,7 @@ UFile (package = ) [public final class SuperCallsKt {...]
UParameter (name = i) [@org.jetbrains.annotations.NotNull var i: int]
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
UBlockExpression [{...}]
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i)] : A
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 1)) [A(i)]
UIdentifier (Identifier (super)) [UIdentifier (Identifier (super))]
USimpleNameReferenceExpression (identifier = A, resolvesTo = PsiClass: A) [A]
USimpleNameReferenceExpression (identifier = i) [i] : int

View File

@@ -126,6 +126,10 @@ class FE1UastApiFixtureTest : KotlinLightCodeInsightFixtureTestCase(), UastApiFi
checkExpressionTypeForCallToInternalOperator(myFixture)
}
fun testExpressionTypeForConstructorDelegationCall() {
checkExpressionTypeForConstructorDelegationCall(myFixture)
}
fun testFlexibleFunctionalInterfaceType() {
checkFlexibleFunctionalInterfaceType(myFixture)
}