FIR: Reimplement implicit types calculator
Make it works through a single component tracking computation status instead of storing it in the nodes
This commit is contained in:
+2
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.*
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformerAdapter
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformerAdapter
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveTransformerAdapter
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveTransformerAdapter
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveTransformerAdapter2
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
|
||||||
// TODO: add FirSession parameter
|
// TODO: add FirSession parameter
|
||||||
@@ -20,7 +21,7 @@ fun FirResolvePhase.createTransformerByPhase(): FirTransformer<Nothing?> {
|
|||||||
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsTransformer()
|
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsTransformer()
|
||||||
TYPES -> FirTypeResolveTransformer()
|
TYPES -> FirTypeResolveTransformer()
|
||||||
STATUS -> FirStatusResolveTransformer()
|
STATUS -> FirStatusResolveTransformer()
|
||||||
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveTransformerAdapter()
|
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveTransformerAdapter2()
|
||||||
BODY_RESOLVE -> FirBodyResolveTransformerAdapter()
|
BODY_RESOLVE -> FirBodyResolveTransformerAdapter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -69,7 +69,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
|
|
||||||
protected inline val symbolProvider: FirSymbolProvider get() = components.symbolProvider
|
protected inline val symbolProvider: FirSymbolProvider get() = components.symbolProvider
|
||||||
|
|
||||||
protected inline val returnTypeCalculator: ReturnTypeCalculator get() = components.returnTypeCalculator
|
|
||||||
protected inline val implicitReceiverStack: ImplicitReceiverStack get() = components.implicitReceiverStack
|
protected inline val implicitReceiverStack: ImplicitReceiverStack get() = components.implicitReceiverStack
|
||||||
protected inline val inferenceComponents: InferenceComponents get() = components.inferenceComponents
|
protected inline val inferenceComponents: InferenceComponents get() = components.inferenceComponents
|
||||||
protected inline val resolutionStageRunner: ResolutionStageRunner get() = components.resolutionStageRunner
|
protected inline val resolutionStageRunner: ResolutionStageRunner get() = components.resolutionStageRunner
|
||||||
@@ -105,7 +104,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
|
|
||||||
override val symbolProvider: FirSymbolProvider = session.firSymbolProvider
|
override val symbolProvider: FirSymbolProvider = session.firSymbolProvider
|
||||||
|
|
||||||
override val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
|
override val returnTypeCalculator: ReturnTypeCalculator = transformer.returnTypeCalculator
|
||||||
override val implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl()
|
override val implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl()
|
||||||
override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
|
override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
|
||||||
override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents)
|
override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents)
|
||||||
|
|||||||
+6
-3
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||||
import org.jetbrains.kotlin.fir.scopes.addImportingScopes
|
import org.jetbrains.kotlin.fir.scopes.addImportingScopes
|
||||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
@@ -26,7 +28,8 @@ open class FirBodyResolveTransformer(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
phase: FirResolvePhase,
|
phase: FirResolvePhase,
|
||||||
override var implicitTypeOnly: Boolean,
|
override var implicitTypeOnly: Boolean,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession,
|
||||||
|
val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
|
||||||
) : FirAbstractBodyResolveTransformer(phase) {
|
) : FirAbstractBodyResolveTransformer(phase) {
|
||||||
private var packageFqName = FqName.ROOT
|
private var packageFqName = FqName.ROOT
|
||||||
|
|
||||||
@@ -173,7 +176,7 @@ open class FirBodyResolveTransformer(
|
|||||||
return declarationsTransformer.transformDeclarationStatus(declarationStatus, data)
|
return declarationsTransformer.transformDeclarationStatus(declarationStatus, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirProperty> {
|
||||||
return declarationsTransformer.transformProperty(property, data)
|
return declarationsTransformer.transformProperty(property, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +188,7 @@ open class FirBodyResolveTransformer(
|
|||||||
return declarationsTransformer.transformAnonymousObject(anonymousObject, data)
|
return declarationsTransformer.transformAnonymousObject(anonymousObject, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult<FirSimpleFunction> {
|
||||||
return declarationsTransformer.transformSimpleFunction(simpleFunction, data)
|
return declarationsTransformer.transformSimpleFunction(simpleFunction, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-14
@@ -74,7 +74,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirProperty> {
|
||||||
return withScopeCleanup(topLevelScopes) {
|
return withScopeCleanup(topLevelScopes) {
|
||||||
prepareTypeParameterOwnerForBodyResolve(property)
|
prepareTypeParameterOwnerForBodyResolve(property)
|
||||||
if (property.isLocal) {
|
if (property.isLocal) {
|
||||||
@@ -120,7 +120,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformLocalVariable(variable: FirProperty): CompositeTransformResult<FirDeclaration> {
|
private fun transformLocalVariable(variable: FirProperty): CompositeTransformResult<FirProperty> {
|
||||||
assert(variable.isLocal)
|
assert(variable.isLocal)
|
||||||
val resolutionMode = withExpectedType(variable.returnTypeRef)
|
val resolutionMode = withExpectedType(variable.returnTypeRef)
|
||||||
variable.transformInitializer(transformer, resolutionMode)
|
variable.transformInitializer(transformer, resolutionMode)
|
||||||
@@ -297,7 +297,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ResolutionMode): CompositeTransformResult<FirSimpleFunction> {
|
||||||
return withScopeCleanup(topLevelScopes) {
|
return withScopeCleanup(topLevelScopes) {
|
||||||
prepareTypeParameterOwnerForBodyResolve(simpleFunction)
|
prepareTypeParameterOwnerForBodyResolve(simpleFunction)
|
||||||
val containingDeclaration = components.containerIfAny
|
val containingDeclaration = components.containerIfAny
|
||||||
@@ -327,21 +327,32 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformFunctionWithGivenSignature(
|
private fun <F : FirFunction<F>> transformFunctionWithGivenSignature(
|
||||||
function: FirFunction<*>,
|
function: F,
|
||||||
returnTypeRef: FirTypeRef
|
returnTypeRef: FirTypeRef
|
||||||
): CompositeTransformResult<FirDeclaration> {
|
): CompositeTransformResult<F> {
|
||||||
if (function is FirSimpleFunction) {
|
if (function is FirSimpleFunction) {
|
||||||
localScopes.lastOrNull()?.storeDeclaration(function)
|
localScopes.lastOrNull()?.storeDeclaration(function)
|
||||||
}
|
}
|
||||||
val result = transformFunction(function, withExpectedType(returnTypeRef)).single as FirFunction<*>
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val result = transformFunction(function, withExpectedType(returnTypeRef)).single as F
|
||||||
|
|
||||||
val body = result.body
|
val body = result.body
|
||||||
return if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
if (result.returnTypeRef is FirImplicitTypeRef) {
|
||||||
result.transformReturnTypeRef(transformer, withExpectedType(body.resultType))
|
if (body != null) {
|
||||||
result
|
result.transformReturnTypeRef(transformer, withExpectedType(body.resultType))
|
||||||
} else {
|
} else {
|
||||||
result
|
result.transformReturnTypeRef(
|
||||||
}.compose()
|
transformer,
|
||||||
|
withExpectedType(
|
||||||
|
FirErrorTypeRefImpl(null, FirSimpleDiagnostic("empty body", DiagnosticKind.Other))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <F : FirFunction<F>> transformFunction(function: FirFunction<F>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
override fun <F : FirFunction<F>> transformFunction(function: FirFunction<F>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
@@ -466,7 +477,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
val writer = FirCallCompletionResultsWriterTransformer(
|
val writer = FirCallCompletionResultsWriterTransformer(
|
||||||
session,
|
session,
|
||||||
ConeSubstitutor.Empty,
|
ConeSubstitutor.Empty,
|
||||||
returnTypeCalculator,
|
components.returnTypeCalculator,
|
||||||
inferenceComponents.approximator,
|
inferenceComponents.approximator,
|
||||||
integerOperatorsTypeUpdater,
|
integerOperatorsTypeUpdater,
|
||||||
integerLiteralTypeApproximator
|
integerLiteralTypeApproximator
|
||||||
|
|||||||
+248
@@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("DuplicatedCode")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.TransformImplicitType
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
|
|
||||||
|
@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")"))
|
||||||
|
class FirImplicitTypeBodyResolveTransformerAdapter2 : FirTransformer<Nothing?>() {
|
||||||
|
private val scopeSession = ScopeSession()
|
||||||
|
private val implicitBodyResolveComputationSession = ImplicitBodyResolveComputationSession()
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||||
|
return element.compose()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirFile> {
|
||||||
|
val session = file.session
|
||||||
|
scopeSession.returnTypeCalculator = MyReturnTypeCalculatorWithJump(session, scopeSession, implicitBodyResolveComputationSession)
|
||||||
|
val transformer = MyFirBodyResolveTransformer(
|
||||||
|
session,
|
||||||
|
scopeSession,
|
||||||
|
implicitBodyResolveComputationSession
|
||||||
|
)
|
||||||
|
return file.transform(transformer, ResolutionMode.ContextIndependent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private open class MyFirBodyResolveTransformer(
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
private val implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession
|
||||||
|
) : FirBodyResolveTransformer(
|
||||||
|
session,
|
||||||
|
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE,
|
||||||
|
implicitTypeOnly = true,
|
||||||
|
scopeSession = scopeSession,
|
||||||
|
returnTypeCalculator = MyReturnTypeCalculatorWithJump(session, scopeSession, implicitBodyResolveComputationSession)
|
||||||
|
) {
|
||||||
|
override fun transformSimpleFunction(
|
||||||
|
simpleFunction: FirSimpleFunction,
|
||||||
|
data: ResolutionMode
|
||||||
|
): CompositeTransformResult<FirSimpleFunction> {
|
||||||
|
return computeCachedTransformationResult(simpleFunction) {
|
||||||
|
super.transformSimpleFunction(simpleFunction, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformProperty(property: FirProperty, data: ResolutionMode): CompositeTransformResult<FirProperty> {
|
||||||
|
return computeCachedTransformationResult(property) {
|
||||||
|
super.transformProperty(property, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <D : FirCallableMemberDeclaration<D>> computeCachedTransformationResult(
|
||||||
|
member: D,
|
||||||
|
transform: () -> CompositeTransformResult<D>
|
||||||
|
): CompositeTransformResult<D> {
|
||||||
|
if (!implicitTypeOnly && member.returnTypeRef is FirResolvedTypeRef) {
|
||||||
|
return transform()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (member.returnTypeRef is FirResolvedTypeRef) return member.compose()
|
||||||
|
val symbol = member.symbol
|
||||||
|
val status = implicitBodyResolveComputationSession.getStatus(symbol)
|
||||||
|
if (status is ImplicitBodyResolveComputationStatus.Computed) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return status.transformedDeclaration.compose() as CompositeTransformResult<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
// If somebody has started resolution recursively (from ReturnTypeCalculator), one has to track it's not being computed already
|
||||||
|
require(status is ImplicitBodyResolveComputationStatus.NotComputed) {
|
||||||
|
"Unexpected status in transformCallableMember ($status) for ${member.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitBodyResolveComputationSession.startComputing(symbol)
|
||||||
|
val result = transform()
|
||||||
|
implicitBodyResolveComputationSession.storeResult(symbol, result.single)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MyReturnTypeCalculatorWithJump(
|
||||||
|
private val session: FirSession,
|
||||||
|
private val scopeSession: ScopeSession,
|
||||||
|
private val implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession
|
||||||
|
) : ReturnTypeCalculator {
|
||||||
|
|
||||||
|
override fun tryCalculateReturnType(declaration: FirTypedDeclaration): FirResolvedTypeRef {
|
||||||
|
if (declaration is FirValueParameter && declaration.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
// TODO?
|
||||||
|
declaration.transformReturnTypeRef(
|
||||||
|
TransformImplicitType,
|
||||||
|
FirErrorTypeRefImpl(
|
||||||
|
null,
|
||||||
|
FirSimpleDiagnostic("Unsupported: implicit VP type")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnTypeRef = declaration.returnTypeRef
|
||||||
|
if (returnTypeRef is FirResolvedTypeRef) return returnTypeRef
|
||||||
|
|
||||||
|
require(declaration is FirCallableMemberDeclaration<*>) { "${declaration::class}: ${declaration.render()}" }
|
||||||
|
|
||||||
|
return when (val status = implicitBodyResolveComputationSession.getStatus(declaration.symbol)) {
|
||||||
|
is ImplicitBodyResolveComputationStatus.Computed -> status.resolvedTypeRef
|
||||||
|
is ImplicitBodyResolveComputationStatus.Computing ->
|
||||||
|
FirErrorTypeRefImpl(null, FirSimpleDiagnostic("cycle", DiagnosticKind.RecursionInImplicitTypes))
|
||||||
|
else -> computeReturnTypeRef(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeReturnTypeRef(declaration: FirCallableMemberDeclaration<*>): FirResolvedTypeRef {
|
||||||
|
val symbol = declaration.symbol
|
||||||
|
val id = symbol.callableId
|
||||||
|
|
||||||
|
val provider = session.firProvider
|
||||||
|
|
||||||
|
val file = provider.getFirCallableContainerFile(symbol)
|
||||||
|
|
||||||
|
val outerClasses = generateSequence(id.classId) { classId ->
|
||||||
|
classId.outerClassId
|
||||||
|
}.mapTo(mutableListOf()) { provider.getFirClassifierByFqName(it) }
|
||||||
|
|
||||||
|
if (file == null || outerClasses.any { it == null }) {
|
||||||
|
return FirErrorTypeRefImpl(
|
||||||
|
null,
|
||||||
|
FirSimpleDiagnostic(
|
||||||
|
"Cannot calculate return type (local class/object?)",
|
||||||
|
DiagnosticKind.InferenceError
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val designation = (listOf(file) + outerClasses.filterNotNull().asReversed() + listOf(declaration))
|
||||||
|
val transformer = MyFirDesignatedBodyResolveTransformer(
|
||||||
|
designation.iterator(),
|
||||||
|
file.session,
|
||||||
|
scopeSession,
|
||||||
|
implicitBodyResolveComputationSession
|
||||||
|
)
|
||||||
|
|
||||||
|
file.transform<FirElement, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
|
||||||
|
|
||||||
|
val transformedDeclaration = transformer.lastResult as? FirCallableMemberDeclaration<*>
|
||||||
|
?: error("Unexpected lastResult: ${transformer.lastResult?.render()}")
|
||||||
|
|
||||||
|
val newReturnTypeRef = transformedDeclaration.returnTypeRef
|
||||||
|
require(newReturnTypeRef is FirResolvedTypeRef) { transformedDeclaration.render() }
|
||||||
|
return newReturnTypeRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MyFirDesignatedBodyResolveTransformer(
|
||||||
|
private val designation: Iterator<FirElement>,
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession
|
||||||
|
) : MyFirBodyResolveTransformer(
|
||||||
|
session,
|
||||||
|
scopeSession,
|
||||||
|
implicitBodyResolveComputationSession
|
||||||
|
) {
|
||||||
|
|
||||||
|
var lastResult: FirElement? = null
|
||||||
|
|
||||||
|
override fun <E : FirElement> transformElement(element: E, data: ResolutionMode): CompositeTransformResult<E> {
|
||||||
|
if (designation.hasNext()) {
|
||||||
|
val result = designation.next().transform<E, ResolutionMode>(this, data).single
|
||||||
|
if (!designation.hasNext()) {
|
||||||
|
lastResult = result
|
||||||
|
}
|
||||||
|
return result.compose()
|
||||||
|
}
|
||||||
|
return super.transformElement(element, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
|
||||||
|
return components.withContainer(declaration) {
|
||||||
|
declaration.replaceResolvePhase(transformerPhase)
|
||||||
|
transformElement(declaration, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImplicitBodyResolveComputationSession {
|
||||||
|
private val implicitBodyResolveStatusMap = hashMapOf<FirCallableSymbol<*>, ImplicitBodyResolveComputationStatus>()
|
||||||
|
|
||||||
|
fun getStatus(symbol: FirCallableSymbol<*>): ImplicitBodyResolveComputationStatus {
|
||||||
|
return implicitBodyResolveStatusMap[symbol] ?: ImplicitBodyResolveComputationStatus.NotComputed
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startComputing(symbol: FirCallableSymbol<*>) {
|
||||||
|
require(implicitBodyResolveStatusMap[symbol] == null) {
|
||||||
|
"Unexpected static in startComputing for $symbol: ${implicitBodyResolveStatusMap[symbol]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitBodyResolveStatusMap[symbol] = ImplicitBodyResolveComputationStatus.Computing
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeResult(
|
||||||
|
symbol: FirCallableSymbol<*>,
|
||||||
|
transformedDeclaration: FirCallableMemberDeclaration<*>
|
||||||
|
) {
|
||||||
|
require(implicitBodyResolveStatusMap[symbol] == ImplicitBodyResolveComputationStatus.Computing) {
|
||||||
|
"Unexpected static in storeResult for $symbol: ${implicitBodyResolveStatusMap[symbol]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnTypeRef = transformedDeclaration.returnTypeRef
|
||||||
|
require(returnTypeRef is FirResolvedTypeRef) {
|
||||||
|
"Not FirResolvedTypeRef (${transformedDeclaration.receiverTypeRef?.render()}) in storeResult for: ${symbol.fir.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitBodyResolveStatusMap[symbol] = ImplicitBodyResolveComputationStatus.Computed(returnTypeRef, transformedDeclaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class ImplicitBodyResolveComputationStatus {
|
||||||
|
object NotComputed : ImplicitBodyResolveComputationStatus()
|
||||||
|
object Computing : ImplicitBodyResolveComputationStatus()
|
||||||
|
|
||||||
|
class Computed(
|
||||||
|
val resolvedTypeRef: FirResolvedTypeRef,
|
||||||
|
val transformedDeclaration: FirCallableMemberDeclaration<*>
|
||||||
|
) : ImplicitBodyResolveComputationStatus()
|
||||||
|
}
|
||||||
+15
-4
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -80,7 +81,8 @@ class FirClassSubstitutionScope(
|
|||||||
useSiteMemberScope.processClassifiersByName(name, processor)
|
useSiteMemberScope.processClassifiersByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val typeCalculator by lazy { ReturnTypeCalculatorWithJump(session, scopeSession) }
|
private val typeCalculator =
|
||||||
|
(scopeSession.returnTypeCalculator as ReturnTypeCalculator?) ?: ReturnTypeCalculatorWithJump(session, scopeSession)
|
||||||
|
|
||||||
private fun ConeKotlinType.substitute(): ConeKotlinType? {
|
private fun ConeKotlinType.substitute(): ConeKotlinType? {
|
||||||
return substitutor.substituteOrNull(this)
|
return substitutor.substituteOrNull(this)
|
||||||
@@ -221,7 +223,7 @@ class FirClassSubstitutionScope(
|
|||||||
FirSimpleFunctionImpl(
|
FirSimpleFunctionImpl(
|
||||||
source,
|
source,
|
||||||
session,
|
session,
|
||||||
baseFunction.returnTypeRef.withReplacedConeType(newReturnType),
|
baseFunction.returnTypeRef.withReplacedReturnType(newReturnType),
|
||||||
baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
||||||
name,
|
name,
|
||||||
baseFunction.status,
|
baseFunction.status,
|
||||||
@@ -286,7 +288,7 @@ class FirClassSubstitutionScope(
|
|||||||
FirPropertyImpl(
|
FirPropertyImpl(
|
||||||
source,
|
source,
|
||||||
session,
|
session,
|
||||||
baseProperty.returnTypeRef.withReplacedConeType(newReturnType),
|
baseProperty.returnTypeRef.withReplacedReturnType(newReturnType),
|
||||||
baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
||||||
name,
|
name,
|
||||||
null,
|
null,
|
||||||
@@ -337,6 +339,16 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unlike other cases, return types may be implicit, i.e. unresolved
|
||||||
|
// But in that cases newType should also be `null`
|
||||||
|
fun FirTypeRef.withReplacedReturnType(newType: ConeKotlinType?): FirTypeRef {
|
||||||
|
require(this is FirResolvedTypeRef || newType == null)
|
||||||
|
if (newType == null) return this
|
||||||
|
|
||||||
|
return FirResolvedTypeRefImpl(source, newType).apply {
|
||||||
|
annotations += this@withReplacedReturnType.annotations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FirTypeRef.withReplacedConeType(newType: ConeKotlinType?): FirResolvedTypeRef {
|
fun FirTypeRef.withReplacedConeType(newType: ConeKotlinType?): FirResolvedTypeRef {
|
||||||
require(this is FirResolvedTypeRef)
|
require(this is FirResolvedTypeRef)
|
||||||
@@ -345,5 +357,4 @@ fun FirTypeRef.withReplacedConeType(newType: ConeKotlinType?): FirResolvedTypeRe
|
|||||||
return FirResolvedTypeRefImpl(source, newType).apply {
|
return FirResolvedTypeRefImpl(source, newType).apply {
|
||||||
annotations += this@withReplacedConeType.annotations
|
annotations += this@withReplacedConeType.annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
|
|||||||
class ScopeSession {
|
class ScopeSession {
|
||||||
private val scopes = hashMapOf<Any, HashMap<ScopeSessionKey<*, *>, FirScope>>()
|
private val scopes = hashMapOf<Any, HashMap<ScopeSessionKey<*, *>, FirScope>>()
|
||||||
|
|
||||||
|
var returnTypeCalculator: Any? = null
|
||||||
|
|
||||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Only for getOrBuild")
|
@Deprecated(level = DeprecationLevel.ERROR, message = "Only for getOrBuild")
|
||||||
fun scopes() = scopes
|
fun scopes() = scopes
|
||||||
|
|
||||||
|
|||||||
Vendored
+6
-6
@@ -7,7 +7,7 @@ object Outer {
|
|||||||
get() = 0
|
get() = 0
|
||||||
|
|
||||||
override fun get(index: Int): Char {
|
override fun get(index: Int): Char {
|
||||||
<!UNRESOLVED_REFERENCE!>checkSubtype<!><CharSequence>(x)
|
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
||||||
return ' '
|
return ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ object Outer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
set(q) {
|
set(q) {
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
checkSubtype<CharSequence>(x)
|
||||||
y = q
|
y = q
|
||||||
x = q
|
x = q
|
||||||
}
|
}
|
||||||
@@ -27,10 +27,10 @@ object Outer {
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
x = y
|
x = y
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
checkSubtype<CharSequence>(x)
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(y)
|
checkSubtype<CharSequence>(y)
|
||||||
|
|
||||||
x.<!UNRESOLVED_REFERENCE!>bar<!>()
|
x.bar()
|
||||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
y.bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -10,8 +10,8 @@ class A {
|
|||||||
val a get() = b
|
val a get() = b
|
||||||
val b get() = a
|
val b get() = a
|
||||||
|
|
||||||
val z1 get() = <!UNRESOLVED_REFERENCE!>id<!>(z1)
|
val z1 get() = <!INAPPLICABLE_CANDIDATE!>id<!>(z1)
|
||||||
val z2 get() = <!UNRESOLVED_REFERENCE!>l<!>(z2)
|
val z2 get() = <!INAPPLICABLE_CANDIDATE!>l<!>(z2)
|
||||||
|
|
||||||
val u get() = field
|
val u get() = field
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class Test {
|
|||||||
val a = y;
|
val a = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
val z = y.<!UNRESOLVED_REFERENCE!>a<!>;
|
val z = y.a;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +24,6 @@ class Test2 {
|
|||||||
val y = 1
|
val y = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val b = a.x
|
val b = a.<!UNRESOLVED_REFERENCE!>x<!>
|
||||||
val c = a.y
|
val c = a.y
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ class Test2 {
|
|||||||
|
|
||||||
val b = <!NI;TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>a<!>.<!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!><!>
|
val b = <!NI;TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>a<!>.<!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!><!>
|
||||||
val c = a.y
|
val c = a.y
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user