FIR: Change transform order in calls/variables to more appropriate
This commit is contained in:
+48
-31
@@ -8,18 +8,14 @@ package org.jetbrains.kotlin.fir.resolve.transformers
|
||||
import com.google.common.collect.LinkedHashMultimap
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultSetterValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
@@ -31,7 +27,6 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOnly: Boolean) : FirTransformer<Any?>() {
|
||||
|
||||
@@ -148,13 +143,13 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
|
||||
private fun <T> storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression {
|
||||
bindingContext[access] =
|
||||
when (val newCallee = access.calleeReference) {
|
||||
is FirErrorNamedReference ->
|
||||
FirErrorTypeRefImpl(session, access.psi, newCallee.errorReason)
|
||||
is FirResolvedCallableReference ->
|
||||
jump.tryCalculateReturnType(newCallee.callableSymbol.firUnsafe())
|
||||
else -> return
|
||||
}
|
||||
when (val newCallee = access.calleeReference) {
|
||||
is FirErrorNamedReference ->
|
||||
FirErrorTypeRefImpl(session, access.psi, newCallee.errorReason)
|
||||
is FirResolvedCallableReference ->
|
||||
jump.tryCalculateReturnType(newCallee.callableSymbol.firUnsafe())
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformQualifiedAccessExpression(
|
||||
@@ -191,26 +186,28 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||
|
||||
val functionCall = functionCall.transformChildren(this, null) as FirFunctionCall
|
||||
|
||||
if (functionCall.calleeReference !is FirSimpleNamedReference) return functionCall.compose()
|
||||
|
||||
val name = functionCall.calleeReference.name
|
||||
|
||||
val expectedTypeRef = data as FirTypeRef?
|
||||
|
||||
functionCall.explicitReceiver?.visitNoTransform(this, null)
|
||||
functionCall.arguments.forEach { it.visitNoTransform(this, null) }
|
||||
val receiver = functionCall.explicitReceiver
|
||||
val arguments = functionCall.arguments
|
||||
|
||||
val checkers = listOf(FunctionApplicabilityChecker(name).apply {
|
||||
expectedType = expectedTypeRef
|
||||
explicitReceiverType = functionCall.explicitReceiver?.resultType
|
||||
parameterCount = functionCall.arguments.size
|
||||
explicitReceiverType = receiver?.resultType
|
||||
parameterCount = arguments.size
|
||||
}, VariableInvokeApplicabilityChecker(name).apply {
|
||||
expectedType = expectedTypeRef
|
||||
variableChecker.apply {
|
||||
expectedType = expectedTypeRef
|
||||
explicitReceiverType = functionCall.explicitReceiver?.resultType
|
||||
explicitReceiverType = receiver?.resultType
|
||||
}
|
||||
parameterCount = functionCall.arguments.size
|
||||
parameterCount = arguments.size
|
||||
})
|
||||
|
||||
|
||||
@@ -220,15 +217,19 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
is VariableInvokeApplicabilityChecker -> {
|
||||
FirFunctionCallImpl(functionCall.session, functionCall.psi, safe = functionCall.safe).apply {
|
||||
calleeReference =
|
||||
functionCall.calleeReference.transformSingle(this@FirBodyResolveTransformer, result.successCandidates())
|
||||
functionCall.calleeReference.transformSingle(this@FirBodyResolveTransformer, result.successCandidates())
|
||||
explicitReceiver =
|
||||
FirQualifiedAccessExpressionImpl(functionCall.session, functionCall.calleeReference.psi, functionCall.safe).apply {
|
||||
calleeReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
result.variableChecker.successCandidates() as List<ConeCallableSymbol>
|
||||
)
|
||||
explicitReceiver = functionCall.explicitReceiver
|
||||
}
|
||||
FirQualifiedAccessExpressionImpl(
|
||||
functionCall.session,
|
||||
functionCall.calleeReference.psi,
|
||||
functionCall.safe
|
||||
).apply {
|
||||
calleeReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
result.variableChecker.successCandidates() as List<ConeCallableSymbol>
|
||||
)
|
||||
explicitReceiver = functionCall.explicitReceiver
|
||||
}
|
||||
}
|
||||
}
|
||||
is ApplicabilityChecker -> {
|
||||
@@ -356,21 +357,37 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
}
|
||||
|
||||
override fun transformVariable(variable: FirVariable, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
val variable = super.transformVariable(variable, variable.returnTypeRef).single as FirVariable
|
||||
val initializer = variable.initializer
|
||||
initializer?.visitNoTransform(this, variable.returnTypeRef)
|
||||
if (variable.returnTypeRef is FirImplicitTypeRef) {
|
||||
when {
|
||||
initializer != null -> {
|
||||
variable.transformReturnTypeRef(this, initializer.resultType)
|
||||
variable.transformReturnTypeRef(
|
||||
this,
|
||||
initializer.resultType ?: FirErrorTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
"No result type for initializer"
|
||||
)
|
||||
)
|
||||
}
|
||||
variable.delegate != null -> {
|
||||
// TODO: type from delegate
|
||||
variable.transformReturnTypeRef(
|
||||
this,
|
||||
FirErrorTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
"Not supported: type from delegate"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (variable !is FirProperty) {
|
||||
localScopes.lastOrNull()?.storeDeclaration(variable)
|
||||
}
|
||||
return super.transformVariable(variable, data)
|
||||
return variable.compose()
|
||||
}
|
||||
|
||||
override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
@@ -380,7 +397,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
|
||||
fun <D> FirElement.visitNoTransform(transformer: FirTransformer<D>, data: D) {
|
||||
val result = this.transform(transformer, data)
|
||||
require(result.single === this)
|
||||
require(result.single === this) { "become ${result.single}: `${result.single.render()}`, was ${this}: `${this.render()}`" }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ FILE: access.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final val x: R|kotlin/Int| = Int(1)
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public final fun abc(): R|kotlin/Int| {
|
||||
^abc R|/Foo.x|
|
||||
@@ -18,7 +18,7 @@ FILE: access.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final val x: R|kotlin/String| = String()
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final fun R|Foo|.abc(): R|kotlin/Int| {
|
||||
^abc R|/Foo.x|
|
||||
|
||||
@@ -9,7 +9,7 @@ FILE: extension.kt
|
||||
}
|
||||
|
||||
public final val x: R|kotlin/Int| = Int(0)
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public final fun foo(): R|Foo| {
|
||||
^foo R|/Foo.x|.R|/Foo.invoke|()
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ FILE: farInvokeExtension.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final val x: R|kotlin/Int| = Int(0)
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
^foo R|/x|()
|
||||
|
||||
+1
-1
@@ -15,4 +15,4 @@ FILE: implicitTypeOrder.kt
|
||||
^create R|/A.A|()
|
||||
}
|
||||
public final val foo: R|A| = R|/create|()
|
||||
public get(): <implicit>
|
||||
public get(): R|A|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FILE: localImplicitBodies.kt
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = object : {
|
||||
lval x: <ERROR TYPE: No result type for initializer> = object : {
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final fun sss(): <ERROR TYPE: Unresolved name: abc> {
|
||||
|
||||
@@ -3,8 +3,8 @@ FILE: simple.kt
|
||||
lval x: R|kotlin/Int| = Int(1)
|
||||
}
|
||||
public final val bar: R|kotlin/String| = String()
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/String|
|
||||
public final val n: R|kotlin/Nothing|? = Null(null)
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/Nothing|?
|
||||
public final val g: R|kotlin/String|? = Null(null)
|
||||
public get(): R|kotlin/String|?
|
||||
|
||||
@@ -63,7 +63,7 @@ FILE: enums.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
public final const val G: R|kotlin/Double| = Double(6.67E-11)
|
||||
public get(): <implicit>
|
||||
public get(): R|kotlin/Double|
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ FILE: simpleClass.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
private final val baz: R|kotlin/Int| = Int(42)
|
||||
private get(): <implicit>
|
||||
private get(): R|kotlin/Int|
|
||||
|
||||
public final override fun foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
^foo <Unresolved name: plus>#(<Unresolved name: plus>#(R|<local>/y|, R|<local>/x|), R|/SomeClass.baz|)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ FILE: simpleClass.kt
|
||||
public constructor(): super<R|kotlin/Any|>()
|
||||
|
||||
private final val baz: R|kotlin/Int| = Int(42)
|
||||
private get(): <implicit>
|
||||
private get(): R|kotlin/Int|
|
||||
|
||||
public final override fun foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| {
|
||||
^foo <Unresolved name: plus>#(<Unresolved name: plus>#(R|<local>/y|, R|<local>/x|), R|/SomeClass.baz|)
|
||||
|
||||
Reference in New Issue
Block a user