[FIR] Properly generate implicit invoke calls for a.(b)()
^KT-64891 Fixed
This commit is contained in:
committed by
Space Team
parent
8e6e447d6d
commit
3a36a786d4
+12
-12
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.fir.lightTree.fir.ValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.lightTree.fir.WhenEntry
|
import org.jetbrains.kotlin.fir.lightTree.fir.WhenEntry
|
||||||
import org.jetbrains.kotlin.fir.lightTree.fir.addDestructuringStatements
|
import org.jetbrains.kotlin.fir.lightTree.fir.addDestructuringStatements
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitThisReference
|
import org.jetbrains.kotlin.fir.references.builder.buildExplicitThisReference
|
||||||
@@ -651,8 +652,8 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
SUPER_EXPRESSION -> {
|
SUPER_EXPRESSION -> {
|
||||||
superNode = node
|
superNode = node
|
||||||
}
|
}
|
||||||
PARENTHESIZED -> node.getExpressionInParentheses()?.let { process(it) } ?: run {
|
PARENTHESIZED -> if (node.tokenType != TokenType.ERROR_ELEMENT) {
|
||||||
additionalArgument = getAsFirExpression(node, "Incorrect invoke receiver")
|
additionalArgument = getAsFirExpression(node.getExpressionInParentheses(), "Incorrect invoke receiver")
|
||||||
}
|
}
|
||||||
TYPE_ARGUMENT_LIST -> {
|
TYPE_ARGUMENT_LIST -> {
|
||||||
firTypeArguments += declarationBuilder.convertTypeArguments(node, allowedUnderscoredTypeArgument = true)
|
firTypeArguments += declarationBuilder.convertTypeArguments(node, allowedUnderscoredTypeArgument = true)
|
||||||
@@ -680,6 +681,15 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
superNode != null || additionalArgument?.calleeReference is FirSuperReference -> {
|
||||||
|
CalleeAndReceiver(
|
||||||
|
buildErrorNamedReference {
|
||||||
|
this.source = superNode?.toFirSourceElement() ?: additionalArgument?.calleeReference?.source
|
||||||
|
diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
additionalArgument != null -> {
|
additionalArgument != null -> {
|
||||||
CalleeAndReceiver(
|
CalleeAndReceiver(
|
||||||
buildSimpleNamedReference {
|
buildSimpleNamedReference {
|
||||||
@@ -691,16 +701,6 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
superNode != null -> {
|
|
||||||
CalleeAndReceiver(
|
|
||||||
buildErrorNamedReference {
|
|
||||||
val node = superNode!!
|
|
||||||
this.source = node.toFirSourceElement()
|
|
||||||
diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> CalleeAndReceiver(
|
else -> CalleeAndReceiver(
|
||||||
buildErrorNamedReference {
|
buildErrorNamedReference {
|
||||||
this.source = source
|
this.source = source
|
||||||
|
|||||||
+24
-10
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -2948,8 +2949,11 @@ open class PsiRawFirBuilder(
|
|||||||
calleeExpression: KtExpression?,
|
calleeExpression: KtExpression?,
|
||||||
defaultSource: KtPsiSourceElement,
|
defaultSource: KtPsiSourceElement,
|
||||||
): CalleeAndReceiver {
|
): CalleeAndReceiver {
|
||||||
return when (calleeExpression) {
|
val parenthesizedArgument = (calleeExpression as? KtParenthesizedExpression)?.expression
|
||||||
is KtSimpleNameExpression ->
|
?.toFirExpression("Incorrect invoke receiver")
|
||||||
|
|
||||||
|
return when {
|
||||||
|
calleeExpression is KtSimpleNameExpression ->
|
||||||
CalleeAndReceiver(
|
CalleeAndReceiver(
|
||||||
buildSimpleNamedReference {
|
buildSimpleNamedReference {
|
||||||
source = calleeExpression.toFirSourceElement()
|
source = calleeExpression.toFirSourceElement()
|
||||||
@@ -2957,22 +2961,32 @@ open class PsiRawFirBuilder(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
is KtParenthesizedExpression -> splitToCalleeAndReceiver(calleeExpression.expression, defaultSource)
|
calleeExpression is KtSuperExpression || parenthesizedArgument?.calleeReference is FirSuperReference -> {
|
||||||
|
|
||||||
null -> {
|
|
||||||
CalleeAndReceiver(
|
CalleeAndReceiver(
|
||||||
buildErrorNamedReference {
|
buildErrorNamedReference {
|
||||||
source = defaultSource
|
source = (calleeExpression as? KtSuperExpression)?.toFirSourceElement()
|
||||||
diagnostic = ConeSyntaxDiagnostic("Call has no callee")
|
?: parenthesizedArgument?.calleeReference?.source
|
||||||
|
diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtSuperExpression -> {
|
parenthesizedArgument != null -> {
|
||||||
|
CalleeAndReceiver(
|
||||||
|
buildSimpleNamedReference {
|
||||||
|
source = defaultSource.fakeElement(KtFakeSourceElementKind.ImplicitInvokeCall)
|
||||||
|
name = OperatorNameConventions.INVOKE
|
||||||
|
},
|
||||||
|
receiverExpression = parenthesizedArgument,
|
||||||
|
isImplicitInvoke = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
calleeExpression == null -> {
|
||||||
CalleeAndReceiver(
|
CalleeAndReceiver(
|
||||||
buildErrorNamedReference {
|
buildErrorNamedReference {
|
||||||
source = calleeExpression.toFirSourceElement()
|
source = defaultSource
|
||||||
diagnostic = ConeSimpleDiagnostic("Super cannot be a callee", DiagnosticKind.SuperNotAllowed)
|
diagnostic = ConeSyntaxDiagnostic("Call has no callee")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FILE: inBrackets.kt
|
FILE: inBrackets.kt
|
||||||
public? final? fun test(e: ( Int.() -> String )): R|kotlin/Unit| {
|
public? final? fun test(e: ( Int.() -> String )): R|kotlin/Unit| {
|
||||||
lval s: <implicit> = IntegerLiteral(3).e#()
|
lval s: <implicit> = IntegerLiteral(3).e#()
|
||||||
lval ss: <implicit> = IntegerLiteral(3).e#()
|
lval ss: <implicit> = e#.invoke#(IntegerLiteral(3))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
// ISSUE: KT-64891
|
|
||||||
|
|
||||||
val b: Int.() -> Int = { 10 }
|
|
||||||
val Int.b: () -> String get() = { "B" }
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
5.(b)().<!UNRESOLVED_REFERENCE!>inv<!>() // should be Int
|
|
||||||
5.b().length // should be String
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> id(it: T) = it
|
|
||||||
|
|
||||||
fun rain() {
|
|
||||||
5.(b)().<!UNRESOLVED_REFERENCE!>inv<!>()
|
|
||||||
5.(id(b))().inv() // should be consistent
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-64891
|
// ISSUE: KT-64891
|
||||||
|
|
||||||
val b: Int.() -> Int = { 10 }
|
val b: Int.() -> Int = { 10 }
|
||||||
|
|||||||
Vendored
+1
-1
@@ -7,5 +7,5 @@ fun test1(f: String.() -> Unit) {
|
|||||||
fun test2(f: (Int) -> Int) {
|
fun test2(f: (Int) -> Int) {
|
||||||
1.<!UNRESOLVED_REFERENCE!>f<!>(2)
|
1.<!UNRESOLVED_REFERENCE!>f<!>(2)
|
||||||
|
|
||||||
2.(<!UNRESOLVED_REFERENCE!>f<!>)(2)
|
2.(f)(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ fun test1() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test2(f: String.(Int) -> Unit) {
|
fun test2(f: String.(Int) -> Unit) {
|
||||||
11.(<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>f<!>)(1)
|
11.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(f)<!>(1)
|
||||||
11.(f)<!NO_VALUE_FOR_PARAMETER!>()<!>
|
11.(f)<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -24,7 +24,7 @@ fun test(a: A, b: B) {
|
|||||||
|
|
||||||
with(b) {
|
with(b) {
|
||||||
a.foo<!NO_VALUE_FOR_PARAMETER!>()<!>
|
a.foo<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
a.(foo)<!NO_VALUE_FOR_PARAMETER!>()<!>
|
<!TOO_MANY_ARGUMENTS!>a<!>.(<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>)()
|
||||||
|
|
||||||
(a.foo)()
|
(a.foo)()
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ fun test(a: A, b: B) {
|
|||||||
|
|
||||||
with(b) {
|
with(b) {
|
||||||
a.foo<!NO_VALUE_FOR_PARAMETER!>()<!>
|
a.foo<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
a.(foo)<!NO_VALUE_FOR_PARAMETER!>()<!>
|
a.(<!UNRESOLVED_REFERENCE!>foo<!>)()
|
||||||
|
|
||||||
(a.foo)()
|
(a.foo)()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -10,10 +10,10 @@ val B.a: () -> Int get() = { 5 }
|
|||||||
fun test(a: A, b: B) {
|
fun test(a: A, b: B) {
|
||||||
val x: Int = b.a()
|
val x: Int = b.a()
|
||||||
|
|
||||||
b.(a)()
|
b.(<!UNRESOLVED_REFERENCE!>a<!>)()
|
||||||
|
|
||||||
with(b) {
|
with(b) {
|
||||||
val y: Int = a()
|
val y: Int = a()
|
||||||
(a)()
|
(<!UNRESOLVED_REFERENCE!>a<!>)()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user