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.resolve.transformers.body.resolve.FirBodyResolveTransformerAdapter
|
||||
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
|
||||
|
||||
// TODO: add FirSession parameter
|
||||
@@ -20,7 +21,7 @@ fun FirResolvePhase.createTransformerByPhase(): FirTransformer<Nothing?> {
|
||||
SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsTransformer()
|
||||
TYPES -> FirTypeResolveTransformer()
|
||||
STATUS -> FirStatusResolveTransformer()
|
||||
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveTransformerAdapter()
|
||||
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveTransformerAdapter2()
|
||||
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 returnTypeCalculator: ReturnTypeCalculator get() = components.returnTypeCalculator
|
||||
protected inline val implicitReceiverStack: ImplicitReceiverStack get() = components.implicitReceiverStack
|
||||
protected inline val inferenceComponents: InferenceComponents get() = components.inferenceComponents
|
||||
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 returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
|
||||
override val returnTypeCalculator: ReturnTypeCalculator = transformer.returnTypeCalculator
|
||||
override val implicitReceiverStack: ImplicitReceiverStack = ImplicitReceiverStackImpl()
|
||||
override val inferenceComponents: InferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
|
||||
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.resolve.ResolutionMode
|
||||
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.types.FirImplicitTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
@@ -26,7 +28,8 @@ open class FirBodyResolveTransformer(
|
||||
session: FirSession,
|
||||
phase: FirResolvePhase,
|
||||
override var implicitTypeOnly: Boolean,
|
||||
scopeSession: ScopeSession
|
||||
scopeSession: ScopeSession,
|
||||
val returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorWithJump(session, scopeSession)
|
||||
) : FirAbstractBodyResolveTransformer(phase) {
|
||||
private var packageFqName = FqName.ROOT
|
||||
|
||||
@@ -173,7 +176,7 @@ open class FirBodyResolveTransformer(
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -185,7 +188,7 @@ open class FirBodyResolveTransformer(
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+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) {
|
||||
prepareTypeParameterOwnerForBodyResolve(property)
|
||||
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)
|
||||
val resolutionMode = withExpectedType(variable.returnTypeRef)
|
||||
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) {
|
||||
prepareTypeParameterOwnerForBodyResolve(simpleFunction)
|
||||
val containingDeclaration = components.containerIfAny
|
||||
@@ -327,21 +327,32 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformFunctionWithGivenSignature(
|
||||
function: FirFunction<*>,
|
||||
private fun <F : FirFunction<F>> transformFunctionWithGivenSignature(
|
||||
function: F,
|
||||
returnTypeRef: FirTypeRef
|
||||
): CompositeTransformResult<FirDeclaration> {
|
||||
): CompositeTransformResult<F> {
|
||||
if (function is FirSimpleFunction) {
|
||||
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
|
||||
return if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
result.transformReturnTypeRef(transformer, withExpectedType(body.resultType))
|
||||
result
|
||||
} else {
|
||||
result
|
||||
}.compose()
|
||||
if (result.returnTypeRef is FirImplicitTypeRef) {
|
||||
if (body != null) {
|
||||
result.transformReturnTypeRef(transformer, withExpectedType(body.resultType))
|
||||
} else {
|
||||
result.transformReturnTypeRef(
|
||||
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> {
|
||||
@@ -466,7 +477,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
val writer = FirCallCompletionResultsWriterTransformer(
|
||||
session,
|
||||
ConeSubstitutor.Empty,
|
||||
returnTypeCalculator,
|
||||
components.returnTypeCalculator,
|
||||
inferenceComponents.approximator,
|
||||
integerOperatorsTypeUpdater,
|
||||
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.ConeSubstitutor
|
||||
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.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -80,7 +81,8 @@ class FirClassSubstitutionScope(
|
||||
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? {
|
||||
return substitutor.substituteOrNull(this)
|
||||
@@ -221,7 +223,7 @@ class FirClassSubstitutionScope(
|
||||
FirSimpleFunctionImpl(
|
||||
source,
|
||||
session,
|
||||
baseFunction.returnTypeRef.withReplacedConeType(newReturnType),
|
||||
baseFunction.returnTypeRef.withReplacedReturnType(newReturnType),
|
||||
baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
||||
name,
|
||||
baseFunction.status,
|
||||
@@ -286,7 +288,7 @@ class FirClassSubstitutionScope(
|
||||
FirPropertyImpl(
|
||||
source,
|
||||
session,
|
||||
baseProperty.returnTypeRef.withReplacedConeType(newReturnType),
|
||||
baseProperty.returnTypeRef.withReplacedReturnType(newReturnType),
|
||||
baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType),
|
||||
name,
|
||||
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 {
|
||||
require(this is FirResolvedTypeRef)
|
||||
@@ -345,5 +357,4 @@ fun FirTypeRef.withReplacedConeType(newType: ConeKotlinType?): FirResolvedTypeRe
|
||||
return FirResolvedTypeRefImpl(source, newType).apply {
|
||||
annotations += this@withReplacedConeType.annotations
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
class ScopeSession {
|
||||
private val scopes = hashMapOf<Any, HashMap<ScopeSessionKey<*, *>, FirScope>>()
|
||||
|
||||
var returnTypeCalculator: Any? = null
|
||||
|
||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Only for getOrBuild")
|
||||
fun scopes() = scopes
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -7,7 +7,7 @@ object Outer {
|
||||
get() = 0
|
||||
|
||||
override fun get(index: Int): Char {
|
||||
<!UNRESOLVED_REFERENCE!>checkSubtype<!><CharSequence>(x)
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
||||
return ' '
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ object Outer {
|
||||
}
|
||||
}
|
||||
set(q) {
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
||||
checkSubtype<CharSequence>(x)
|
||||
y = q
|
||||
x = q
|
||||
}
|
||||
@@ -27,10 +27,10 @@ object Outer {
|
||||
fun foo() {
|
||||
x = y
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(x)
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><CharSequence>(y)
|
||||
checkSubtype<CharSequence>(x)
|
||||
checkSubtype<CharSequence>(y)
|
||||
|
||||
x.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
x.bar()
|
||||
y.bar()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ class A {
|
||||
val a get() = b
|
||||
val b get() = a
|
||||
|
||||
val z1 get() = <!UNRESOLVED_REFERENCE!>id<!>(z1)
|
||||
val z2 get() = <!UNRESOLVED_REFERENCE!>l<!>(z2)
|
||||
val z1 get() = <!INAPPLICABLE_CANDIDATE!>id<!>(z1)
|
||||
val z2 get() = <!INAPPLICABLE_CANDIDATE!>l<!>(z2)
|
||||
|
||||
val u get() = field
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class Test {
|
||||
val a = y;
|
||||
}
|
||||
|
||||
val z = y.<!UNRESOLVED_REFERENCE!>a<!>;
|
||||
val z = y.a;
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@ class Test2 {
|
||||
val y = 1
|
||||
}
|
||||
|
||||
val b = a.x
|
||||
val b = a.<!UNRESOLVED_REFERENCE!>x<!>
|
||||
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 c = a.y
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user