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:
Denis Zharkov
2020-01-23 11:35:56 +03:00
parent f256547cc8
commit c295f2dc25
11 changed files with 311 additions and 36 deletions
@@ -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()
} }
} }
@@ -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)
@@ -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)
} }
@@ -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
@@ -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,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
@@ -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()
} }
} }
@@ -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
} }
+1 -1
View File
@@ -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
} }