[LL FIR] rewrite LLFirSuperTypeTargetResolver
The previous implementation had issues with locks, publication and performance Also, this change fixed a problem with mixed cycle inheritance ^KT-56550 ^KTIJ-25430 Fixed ^KTIJ-23520 Fixed ^KT-57623 Fixed ^KTIJ-25372 Fixed ^KT-58357 Fixed
This commit is contained in:
committed by
Space Team
parent
09d17d88d7
commit
c2b09d3b1e
+1
-1
@@ -53,7 +53,7 @@ internal sealed class KtFirNamedClassOrObjectSymbolBase : KtNamedClassOrObjectSy
|
|||||||
// Shared Operations
|
// Shared Operations
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
override val superTypes: List<KtType> by cached {
|
override val superTypes: List<KtType> by cached {
|
||||||
firSymbol.superTypesAndAnnotationsListForRegularClass(builder)
|
firSymbol.superTypesList(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
context(KtAnalysisSession)
|
context(KtAnalysisSession)
|
||||||
|
|||||||
+1
-16
@@ -8,26 +8,11 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtReceiverParameterSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtReceiverParameterSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.declarations.resolvePhase
|
|
||||||
|
|
||||||
internal fun FirClassSymbol<*>.superTypesList(builder: KtSymbolByFirBuilder): List<KtType> =
|
internal fun FirClassSymbol<*>.superTypesList(builder: KtSymbolByFirBuilder): List<KtType> = resolvedSuperTypeRefs.mapToKtType(builder)
|
||||||
resolvedSuperTypeRefs.mapToKtType(builder)
|
|
||||||
|
|
||||||
internal fun FirRegularClassSymbol.superTypesAndAnnotationsListForRegularClass(builder: KtSymbolByFirBuilder): List<KtType> {
|
|
||||||
val fir = fir
|
|
||||||
|
|
||||||
if (fir.resolvePhase >= FirResolvePhase.SUPER_TYPES) {
|
|
||||||
return fir.superTypeRefs.mapToKtType(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fir.resolveSupertypesInTheAir(builder.rootSession).mapToKtType(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun List<FirTypeRef>.mapToKtType(
|
private fun List<FirTypeRef>.mapToKtType(
|
||||||
builder: KtSymbolByFirBuilder,
|
builder: KtSymbolByFirBuilder,
|
||||||
|
|||||||
+242
-189
@@ -5,36 +5,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.asResolveTarget
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.LLFirPhaseUpdater
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.LLFirPhaseUpdater
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkPhase
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkPhase
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkTypeRefIsResolved
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkTypeRefIsResolved
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withInvalidationOnException
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||||
import org.jetbrains.kotlin.fir.render
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirApplySupertypesTransformer
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationSession
|
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationStatus
|
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationStatus
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataContextCollector
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.platformSupertypeUpdater
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.type
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
|
||||||
|
|
||||||
internal object LLFirSupertypeLazyResolver : LLFirLazyResolver(FirResolvePhase.SUPER_TYPES) {
|
internal object LLFirSupertypeLazyResolver : LLFirLazyResolver(FirResolvePhase.SUPER_TYPES) {
|
||||||
override fun resolve(
|
override fun resolve(
|
||||||
@@ -70,14 +65,19 @@ internal object LLFirSupertypeLazyResolver : LLFirLazyResolver(FirResolvePhase.S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class LLFirSuperTypeTargetResolver(
|
private class LLFirSuperTypeTargetResolver(
|
||||||
target: LLFirResolveTarget,
|
target: LLFirResolveTarget,
|
||||||
lockProvider: LLFirLockProvider,
|
lockProvider: LLFirLockProvider,
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val scopeSession: ScopeSession,
|
private val scopeSession: ScopeSession,
|
||||||
|
private val supertypeComputationSession: LLFirSupertypeComputationSession = LLFirSupertypeComputationSession(session),
|
||||||
|
private val visitedElements: MutableSet<FirElementWithResolveState> = hashSetOf(),
|
||||||
) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.SUPER_TYPES, isJumpingPhase = true) {
|
) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.SUPER_TYPES, isJumpingPhase = true) {
|
||||||
|
private val supertypeResolver = FirSupertypeResolverVisitor(
|
||||||
private val supertypeComputationSession = SupertypeComputationSession()
|
session = session,
|
||||||
|
supertypeComputationSession = supertypeComputationSession,
|
||||||
|
scopeSession = scopeSession,
|
||||||
|
)
|
||||||
|
|
||||||
override fun withFile(firFile: FirFile, action: () -> Unit) {
|
override fun withFile(firFile: FirFile, action: () -> Unit) {
|
||||||
action()
|
action()
|
||||||
@@ -85,203 +85,256 @@ internal class LLFirSuperTypeTargetResolver(
|
|||||||
|
|
||||||
@Deprecated("Should never be called directly, only for override purposes, please use withRegularClass", level = DeprecationLevel.ERROR)
|
@Deprecated("Should never be called directly, only for override purposes, please use withRegularClass", level = DeprecationLevel.ERROR)
|
||||||
override fun withRegularClassImpl(firClass: FirRegularClass, action: () -> Unit) {
|
override fun withRegularClassImpl(firClass: FirRegularClass, action: () -> Unit) {
|
||||||
doResolveWithoutLock(firClass)
|
supertypeResolver.withClass(firClass) {
|
||||||
action()
|
doResolveWithoutLock(firClass)
|
||||||
|
action()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doResolveWithoutLock(target: FirElementWithResolveState): Boolean {
|
override fun doResolveWithoutLock(target: FirElementWithResolveState): Boolean {
|
||||||
|
val isVisited = !visitedElements.add(target)
|
||||||
|
if (isVisited) return true
|
||||||
|
|
||||||
when (target) {
|
when (target) {
|
||||||
is FirRegularClass, is FirTypeAlias -> {
|
is FirRegularClass -> performResolve(
|
||||||
val designationToResolve = FirDesignationWithFile(nestedClassesStack, target, resolveTarget.firFile)
|
declaration = target,
|
||||||
val collected = collect(designationToResolve)
|
resolver = { target.resolveSupertypeRefs() },
|
||||||
supertypeComputationSession.breakLoops(session)
|
superTypeUpdater = {
|
||||||
apply(collected)
|
target.replaceSuperTypeRefs(it)
|
||||||
}
|
session.platformSupertypeUpdater?.updateSupertypesIfNeeded(target, scopeSession)
|
||||||
else -> {
|
},
|
||||||
performCustomResolveUnderLock(target) {
|
)
|
||||||
// just update the phase
|
is FirTypeAlias -> performResolve(
|
||||||
}
|
declaration = target,
|
||||||
|
resolver = { target.resolveExpandedTypeRef() },
|
||||||
|
superTypeUpdater = { target.replaceExpandedTypeRef(it.single()) },
|
||||||
|
)
|
||||||
|
else -> performCustomResolveUnderLock(target) {
|
||||||
|
// just update the phase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass.resolveSupertypeRefs(): List<FirResolvedTypeRef> {
|
||||||
|
val superTypeRefs = superTypeRefs
|
||||||
|
/**
|
||||||
|
* TODO: KT-56551 this is safe, because we have a global phase lock
|
||||||
|
* Without such lock we should make a copy of [superTypeRefs] under a lock or
|
||||||
|
* FirRegularClassImpl should have "var superTypeRefs" + assign instead of "val superTypeRefs" + mutation
|
||||||
|
*/
|
||||||
|
return supertypeResolver.resolveSpecificClassLikeSupertypes(this, superTypeRefs)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirTypeAlias.resolveExpandedTypeRef(): List<FirResolvedTypeRef> {
|
||||||
|
val expandedTypeRef = expandedTypeRef
|
||||||
|
return supertypeResolver.resolveTypeAliasSupertype(this, expandedTypeRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T : FirClassLikeDeclaration> performResolve(
|
||||||
|
declaration: T,
|
||||||
|
resolver: () -> List<FirResolvedTypeRef>,
|
||||||
|
crossinline superTypeUpdater: (List<FirTypeRef>) -> Unit,
|
||||||
|
) {
|
||||||
|
// To avoid redundant work, because a publication won't be executed
|
||||||
|
if (declaration.resolvePhase >= resolverPhase) return
|
||||||
|
|
||||||
|
declaration.lazyResolveToPhase(resolverPhase.previous)
|
||||||
|
|
||||||
|
// 1. Resolve declaration super type refs
|
||||||
|
val resolvedSuperTypeRefs = resolver()
|
||||||
|
|
||||||
|
// 2. Resolve super declarations
|
||||||
|
val status = supertypeComputationSession.getSupertypesComputationStatus(declaration)
|
||||||
|
if (status is SupertypeComputationStatus.Computed) {
|
||||||
|
for (computedType in status.supertypeRefs) {
|
||||||
|
crawlSupertype(computedType.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Find loops
|
||||||
|
val loopedSuperTypeRefs = supertypeComputationSession.findLoopFor(declaration)
|
||||||
|
|
||||||
|
// 4. Get error type refs or already resolved
|
||||||
|
val resultedTypeRefs = loopedSuperTypeRefs ?: resolvedSuperTypeRefs
|
||||||
|
|
||||||
|
// 5. Publish the result
|
||||||
|
performCustomResolveUnderLock(declaration) {
|
||||||
|
superTypeUpdater(resultedTypeRefs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We want to apply resolved supertypes to as many designations as possible.
|
||||||
|
* So we crawl the resolved supertypes of visited designations to find more designations to collect.
|
||||||
|
*/
|
||||||
|
private fun crawlSupertype(type: ConeKotlinType) {
|
||||||
|
val classLikeDeclaration = type.toSymbol(session)?.fir
|
||||||
|
if (classLikeDeclaration !is FirClassLikeDeclaration) return
|
||||||
|
if (classLikeDeclaration in visitedElements) return
|
||||||
|
if (classLikeDeclaration is FirJavaClass) {
|
||||||
|
if (!classLikeDeclaration.canHaveLoopInSupertypesHierarchy(session)) return
|
||||||
|
|
||||||
|
visitedElements += classLikeDeclaration
|
||||||
|
val parentClass = classLikeDeclaration.outerClass(session)
|
||||||
|
if (parentClass != null) {
|
||||||
|
crawlSupertype(parentClass.defaultType())
|
||||||
|
}
|
||||||
|
|
||||||
|
classLikeDeclaration.superTypeRefs.filterIsInstance<FirResolvedTypeRef>().forEach {
|
||||||
|
crawlSupertype(it.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolveTarget = classLikeDeclaration.takeIf { it.canHaveLoopInSupertypesHierarchy(session, forceSkipResolvedClasses = true) }
|
||||||
|
?.tryCollectDesignationWithFile()
|
||||||
|
?.asResolveTarget()
|
||||||
|
|
||||||
|
if (resolveTarget != null) {
|
||||||
|
LLFirSuperTypeTargetResolver(
|
||||||
|
target = resolveTarget,
|
||||||
|
lockProvider = lockProvider,
|
||||||
|
session = session,
|
||||||
|
scopeSession = scopeSession,
|
||||||
|
supertypeComputationSession = supertypeComputationSession,
|
||||||
|
visitedElements = visitedElements,
|
||||||
|
).resolveDesignation()
|
||||||
|
|
||||||
|
LLFirLazyPhaseResolverByPhase.getByPhase(resolverPhase).checkIsResolved(resolveTarget)
|
||||||
|
} else if (type is ConeClassLikeType) {
|
||||||
|
// The `classLikeDeclaration` is not associated with a file, and thus there is no need to resolve it, but it may still point
|
||||||
|
// to declarations via its type arguments which need to be collected and have a containing file.
|
||||||
|
// For example, a `Function1` could point to a type alias.
|
||||||
|
type.typeArguments.forEach { it.type?.let(::crawlSupertype) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
||||||
error("Should be resolved without lock in ${::doResolveWithoutLock.name}")
|
error("Should be resolved without lock in ${::doResolveWithoutLock.name}")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inner class DesignatedFirSupertypeResolverVisitor(classDesignation: FirDesignation) :
|
/**
|
||||||
FirSupertypeResolverVisitor(
|
* We shouldn't skip Java source classes because they're marked as BODY_RESOLVE,
|
||||||
|
* but this doesn't give us knowledge about its participation in the calculation of supertypes.
|
||||||
|
* The contract here – if a declaration is already resolved to FirResolvePhase.SUPER_TYPES or higher that this
|
||||||
|
* means that this class can't have loop with our class, because in this case this declaration will be present
|
||||||
|
* in the current supertypes resolve session
|
||||||
|
*/
|
||||||
|
private fun FirClassLikeDeclaration.canHaveLoopInSupertypesHierarchy(
|
||||||
|
session: FirSession,
|
||||||
|
forceSkipResolvedClasses: Boolean = false,
|
||||||
|
): Boolean = when {
|
||||||
|
this is FirJavaClass -> origin is FirDeclarationOrigin.Java.Source
|
||||||
|
resolvePhase < FirResolvePhase.SUPER_TYPES -> true
|
||||||
|
|
||||||
|
// We should still process resolved if it has loop in super type refs, because we can be part of this cycle
|
||||||
|
!forceSkipResolvedClasses && this is FirRegularClass -> hasLoopInSupertypeRefs(session)
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass.outerClass(session: FirSession): FirRegularClass? = symbol.classId.parentClassId?.let { parentClassId ->
|
||||||
|
session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)?.fir as? FirRegularClass
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class must be already resolved
|
||||||
|
*/
|
||||||
|
private fun FirRegularClass.hasLoopInSupertypeRefs(session: FirSession): Boolean {
|
||||||
|
if (superTypeRefs.any(FirTypeRef::isLoopedSupertypeRef)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return outerClass(session)?.hasLoopInSupertypeRefs(session) == true
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirTypeRef.isLoopedSupertypeRef: Boolean
|
||||||
|
get() {
|
||||||
|
if (this !is FirErrorTypeRef) return false
|
||||||
|
val diagnostic = diagnostic
|
||||||
|
return diagnostic is ConeSimpleDiagnostic && diagnostic.kind == DiagnosticKind.LoopInSupertype
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LLFirSupertypeComputationSession(private val session: FirSession) : SupertypeComputationSession() {
|
||||||
|
/**
|
||||||
|
* These collections exist to reuse a collection for each search to avoid repeated memory allocation.
|
||||||
|
* Can be replaced with a new collection on each invocation of [findLoopFor]
|
||||||
|
*/
|
||||||
|
private val visited: MutableSet<FirClassLikeDeclaration> = hashSetOf()
|
||||||
|
private val looped: MutableSet<FirClassLikeDeclaration> = hashSetOf()
|
||||||
|
private val pathSet: MutableSet<FirClassLikeDeclaration> = hashSetOf()
|
||||||
|
private val path: MutableList<FirClassLikeDeclaration> = mutableListOf()
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map from [FirClassLikeDeclaration] to [List<FirResolvedTypeRef>>],
|
||||||
|
* where the list contains at least one [FirErrorTypeRef] for looped references
|
||||||
|
*/
|
||||||
|
private val updatedTypesForDeclarationsWithLoop: MutableMap<FirClassLikeDeclaration, List<FirResolvedTypeRef>> = hashMapOf()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param declaration declaration to be checked for loops
|
||||||
|
* @return list of resolved super type refs if at least one of them is [FirErrorTypeRef] due to cycle hierarchy
|
||||||
|
*/
|
||||||
|
fun findLoopFor(declaration: FirClassLikeDeclaration): List<FirResolvedTypeRef>? {
|
||||||
|
breakLoopFor(
|
||||||
|
declaration = declaration,
|
||||||
session = session,
|
session = session,
|
||||||
supertypeComputationSession = supertypeComputationSession,
|
visited = visited,
|
||||||
scopeSession = scopeSession,
|
looped = looped,
|
||||||
scopeForLocalClass = null,
|
pathSet = pathSet,
|
||||||
localClassesNavigationInfo = null,
|
path = path,
|
||||||
) {
|
)
|
||||||
val declarationTransformer = LLFirDeclarationTransformer(classDesignation)
|
|
||||||
|
|
||||||
override fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
require(path.isEmpty()) { "Path should be empty" }
|
||||||
declarationTransformer.visitDeclarationContent(this, declaration, data) {
|
require(pathSet.isEmpty()) { "Path set should be empty" }
|
||||||
super.visitDeclarationContent(declaration, data)
|
visited.clear()
|
||||||
declaration
|
looped.clear()
|
||||||
}
|
return updatedTypesForDeclarationsWithLoop[declaration]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class DesignatedFirApplySupertypesTransformer(classDesignation: FirDesignation) :
|
override fun isAlreadyResolved(classLikeDeclaration: FirClassLikeDeclaration): Boolean {
|
||||||
FirApplySupertypesTransformer(supertypeComputationSession, session, scopeSession) {
|
return !classLikeDeclaration.canHaveLoopInSupertypesHierarchy(session)
|
||||||
|
|
||||||
val declarationTransformer = LLFirDeclarationTransformer(classDesignation)
|
|
||||||
|
|
||||||
override fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
|
|
||||||
return declarationTransformer.transformDeclarationContent(this, declaration, data) {
|
|
||||||
super.transformDeclarationContent(declaration, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class DesignationCollector {
|
|
||||||
private val visited = mutableMapOf<FirElementWithResolveState, FirDesignationWithFile>()
|
|
||||||
private val toVisit = mutableListOf<FirDesignationWithFile>()
|
|
||||||
|
|
||||||
fun collect(designation: FirDesignationWithFile): Collection<FirDesignationWithFile> {
|
|
||||||
toVisit.add(designation)
|
|
||||||
while (toVisit.isNotEmpty()) {
|
|
||||||
toVisit.forEach(::visitDesignation)
|
|
||||||
toVisit.clear()
|
|
||||||
|
|
||||||
// We want to apply resolved supertypes to as many designations as possible. So we crawl the resolved supertypes of visited
|
|
||||||
// designations to find more designations to collect.
|
|
||||||
for (supertypeComputationStatus in supertypeComputationSession.supertypeStatusMap.values) {
|
|
||||||
if (supertypeComputationStatus !is SupertypeComputationStatus.Computed) continue
|
|
||||||
supertypeComputationStatus.supertypeRefs.forEach { crawlSupertype(it.type) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return visited.values
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun visitDesignation(designation: FirDesignationWithFile) {
|
|
||||||
checkCanceled()
|
|
||||||
val resolver = DesignatedFirSupertypeResolverVisitor(designation)
|
|
||||||
designation.firFile.lazyResolveToPhase(FirResolvePhase.IMPORTS)
|
|
||||||
designation.firFile.accept(resolver, null)
|
|
||||||
resolver.declarationTransformer.ensureDesignationPassed()
|
|
||||||
visited[designation.target] = designation
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun crawlSupertype(type: ConeKotlinType) {
|
|
||||||
val classLikeDeclaration = type.toSymbol(session)?.fir
|
|
||||||
if (classLikeDeclaration !is FirClassLikeDeclaration) return
|
|
||||||
if (classLikeDeclaration is FirJavaClass) return
|
|
||||||
if (visited.containsKey(classLikeDeclaration)) return
|
|
||||||
|
|
||||||
val containingFile =
|
|
||||||
classLikeDeclaration.llFirResolvableSession?.moduleComponents?.cache?.getContainerFirFile(classLikeDeclaration)
|
|
||||||
if (containingFile != null) {
|
|
||||||
toVisit.add(classLikeDeclaration.collectDesignation(containingFile))
|
|
||||||
} else if (type is ConeClassLikeType) {
|
|
||||||
// The `classLikeDeclaration` is not associated with a file and thus there is no need to resolve it, but it may still point
|
|
||||||
// to declarations via its type arguments which need to be collected and have a containing file. For example, a `Function1`
|
|
||||||
// could point to a type alias.
|
|
||||||
type.typeArguments.forEach { it.type?.let(::crawlSupertype) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the supertypes of [designation] and collects all designations that resolved supertypes should be applied to, including
|
* We shouldn't try to iterate over unresolved class. Otherwise, it can lead to [ConcurrentModificationException]
|
||||||
* [designation] itself and any designations discovered via resolved supertypes.
|
|
||||||
*/
|
*/
|
||||||
private fun collect(designation: FirDesignationWithFile): Collection<FirDesignationWithFile> =
|
override fun getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration: FirClassLikeDeclaration): List<FirResolvedTypeRef>? {
|
||||||
DesignationCollector().collect(designation)
|
if (classLikeDeclaration.resolvePhase < FirResolvePhase.SUPER_TYPES) return emptyList()
|
||||||
|
|
||||||
|
return super.getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the resolved supertypes in [supertypeComputationSession] to each designation in [designations].
|
* It is possible that one of super type refs were already reported as an error, but the second – not.
|
||||||
|
* So in this case, we want to save already reported errors and add a new one.
|
||||||
|
* Example:
|
||||||
|
* ```
|
||||||
|
* interface B : A, ResolveMe {}
|
||||||
|
* interface C : B {}
|
||||||
|
* interface D : B {}
|
||||||
|
* interface ResolveMe<caret> : F {}
|
||||||
|
* // D will be marked as error during ResolveMe->F->D->B->ResolveMe round.
|
||||||
|
* // And we will back to super type refs of class F during the resolution of class C
|
||||||
|
* interface F : D, C {}
|
||||||
|
* interface NonLoopedInterface : C
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
private fun apply(designations: Collection<FirDesignationWithFile>) {
|
override fun reportLoopErrorRefs(classLikeDeclaration: FirClassLikeDeclaration, supertypeRefs: List<FirResolvedTypeRef>) {
|
||||||
fun applyToFileSymbols(designations: List<FirDesignationWithFile>) {
|
updatedTypesForDeclarationsWithLoop.merge(classLikeDeclaration, supertypeRefs) { oldRefs, newRefs ->
|
||||||
for (designation in designations) {
|
buildList<FirResolvedTypeRef>(oldRefs.size) {
|
||||||
checkCanceled()
|
for ((old, new) in oldRefs.zip(newRefs)) {
|
||||||
val applier = DesignatedFirApplySupertypesTransformer(designation)
|
if (old is FirErrorTypeRef) {
|
||||||
(designation.target as FirDeclaration).lazyResolveToPhase(resolverPhase.previous)
|
add(old)
|
||||||
performCustomResolveUnderLock(designation.target) {
|
} else {
|
||||||
designation.firFile.transform<FirElement, Void?>(applier, null)
|
add(new)
|
||||||
applier.declarationTransformer.ensureDesignationPassed()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val filesToDesignations = designations.groupBy { it.firFile }
|
|
||||||
for (designationsPerFile in filesToDesignations) {
|
|
||||||
checkCanceled()
|
|
||||||
val session = designationsPerFile.key.llFirResolvableSession
|
|
||||||
?: error("When FirFile exists for the declaration, the session should be resolvable")
|
|
||||||
withInvalidationOnException(session) {
|
|
||||||
applyToFileSymbols(designationsPerFile.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LLFirDeclarationTransformer(private val designation: FirDesignation) {
|
|
||||||
private val designationWithoutTargetIterator = designation.toSequence(includeTarget = false).iterator()
|
|
||||||
private var isInsideTargetDeclaration: Boolean = false
|
|
||||||
private var designationPassed: Boolean = false
|
|
||||||
|
|
||||||
inline fun <D> visitDeclarationContent(
|
|
||||||
visitor: FirVisitor<Unit, D>,
|
|
||||||
declaration: FirDeclaration,
|
|
||||||
data: D,
|
|
||||||
default: () -> FirDeclaration
|
|
||||||
): FirDeclaration = processDeclarationContent(declaration, default) {
|
|
||||||
it.accept(visitor, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <D> transformDeclarationContent(
|
|
||||||
transformer: FirDefaultTransformer<D>,
|
|
||||||
declaration: FirDeclaration,
|
|
||||||
data: D,
|
|
||||||
default: () -> FirDeclaration
|
|
||||||
): FirDeclaration = processDeclarationContent(declaration, default) { toTransform ->
|
|
||||||
toTransform.transform<FirElement, D>(transformer, data).also { transformed ->
|
|
||||||
check(transformed === toTransform) {
|
|
||||||
"become $transformed `${transformed.render()}`, was ${toTransform}: `${toTransform.render()}`"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun processDeclarationContent(
|
|
||||||
declaration: FirDeclaration,
|
|
||||||
default: () -> FirDeclaration,
|
|
||||||
applyToDesignated: (FirElementWithResolveState) -> Unit,
|
|
||||||
): FirDeclaration {
|
|
||||||
//It means that we are inside the target declaration
|
|
||||||
if (isInsideTargetDeclaration) {
|
|
||||||
return default()
|
|
||||||
}
|
|
||||||
|
|
||||||
//It means that we already transform target declaration and now can skip all others
|
|
||||||
if (designationPassed) {
|
|
||||||
return declaration
|
|
||||||
}
|
|
||||||
|
|
||||||
if (designationWithoutTargetIterator.hasNext()) {
|
|
||||||
applyToDesignated(designationWithoutTargetIterator.next())
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
isInsideTargetDeclaration = true
|
|
||||||
designationPassed = true
|
|
||||||
applyToDesignated(designation.target)
|
|
||||||
} finally {
|
|
||||||
isInsideTargetDeclaration = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return declaration
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ensureDesignationPassed() {
|
|
||||||
check(designationPassed) { "Designation not passed for declaration ${designation.target::class.simpleName}" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
interface B : A, ResolveMe {}
|
||||||
|
interface C : B {}
|
||||||
|
interface D : B {}
|
||||||
|
interface ResolveMe<caret> : F {}
|
||||||
|
interface F : D, C {}
|
||||||
|
interface NonLoopedInterface : C
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(COMPANION_GENERATION)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(TYPES)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(STATUS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(EXPECT_ACTUAL_MATCHING)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(CONTRACTS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface NonLoopedInterface : R|C| {
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
interface Resolve<caret>Me : A, E {}
|
||||||
|
interface C : ResolveMe {}
|
||||||
|
interface D : ResolveMe {}
|
||||||
|
interface E : F {}
|
||||||
|
interface F : D, C {}
|
||||||
|
interface NonLoopedInterface : C
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : A, E {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface E : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : A, E {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface E : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] interface ResolveMe : A, E {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface E : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(COMPANION_GENERATION)] interface ResolveMe : A, E {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D : ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface E : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D, C {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(TYPES)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(STATUS)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(EXPECT_ACTUAL_MATCHING)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(CONTRACTS)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C {
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy2.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /E> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface C : <ERROR TYPE REF: Loop in supertype: /C -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface D : <ERROR TYPE REF: Loop in supertype: /D -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface E : <ERROR TYPE REF: Loop in supertype: /E -> /F> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D>, <ERROR TYPE REF: Loop in supertype: /F -> /C> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface NonLoopedInterface : R|C| {
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
interface B : A, ResolveMe {}
|
||||||
|
interface C1 : B {}
|
||||||
|
interface C2 : C1 {}
|
||||||
|
interface D1 : B {}
|
||||||
|
interface D2 : D1 {}
|
||||||
|
interface ResolveMe<caret> : F {}
|
||||||
|
interface F : D2, C2 {}
|
||||||
|
interface NonLoopedInterface : C2
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C2 : C1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D2 : D1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D2, C2 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C2 : C1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D2 : D1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D2, C2 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C2 : C1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D2 : D1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D2, C2 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface B : A, ResolveMe {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface C2 : C1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D1 : B {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface D2 : D1 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(COMPANION_GENERATION)] interface ResolveMe : F {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface F : D2, C2 {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(TYPES)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(STATUS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(EXPECT_ACTUAL_MATCHING)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(CONTRACTS)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(SUPER_TYPES)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public? final? [ResolvedTo(RAW_FIR)] interface NonLoopedInterface : C2 {
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicHierarchy3.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface B : <ERROR TYPE REF: Symbol not found for A>, <ERROR TYPE REF: Loop in supertype: /B -> /ResolveMe> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface C1 : <ERROR TYPE REF: Loop in supertype: /C1 -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface C2 : <ERROR TYPE REF: Loop in supertype: /C2 -> /C1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface D1 : <ERROR TYPE REF: Loop in supertype: /D1 -> /B> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface D2 : <ERROR TYPE REF: Loop in supertype: /D2 -> /D1> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface ResolveMe : <ERROR TYPE REF: Loop in supertype: /ResolveMe -> /F> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface F : <ERROR TYPE REF: Loop in supertype: /F -> /D2>, <ERROR TYPE REF: Loop in supertype: /F -> /C2> {
|
||||||
|
}
|
||||||
|
public abstract [ResolvedTo(BODY_RESOLVE)] interface NonLoopedInterface : R|C2| {
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
open class <caret>C : D() {
|
||||||
|
open class CC
|
||||||
|
}
|
||||||
|
open class D : C.CC()
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(COMPANION_GENERATION)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(STATUS)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(EXPECT_ACTUAL_MATCHING)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(CONTRACTS)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
super<R|D|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(STATUS)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
super<R|D|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
super<R|C.CC|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
open class C : D() {
|
||||||
|
open class CC
|
||||||
|
}
|
||||||
|
open class <caret>D : C.CC()
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
RAW_FIR:
|
||||||
|
FILE: [ResolvedTo(RAW_FIR)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPORTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPILER_REQUIRED_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPANION_GENERATION:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class C : D {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(RAW_FIR)] class CC : R|kotlin/Any| {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(COMPANION_GENERATION)] class D : C.CC {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER_TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPES:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public? open [ResolvedTo(TYPES)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<C.CC>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(STATUS)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_ACTUAL_MATCHING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(EXPECT_ACTUAL_MATCHING)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGUMENTS_OF_ANNOTATIONS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTRACTS:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(CONTRACTS)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLICIT_TYPES_BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATIONS_ARGUMENTS_MAPPING:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<D>
|
||||||
|
}
|
||||||
|
|
||||||
|
public? open [ResolvedTo(SUPER_TYPES)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
LAZY_super<R|C.CC|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BODY_RESOLVE:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(RAW_FIR)] annotations container
|
||||||
|
public open [ResolvedTo(STATUS)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
LAZY_super<R|D|>
|
||||||
|
}
|
||||||
|
|
||||||
|
public open [ResolvedTo(STATUS)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public [ResolvedTo(STATUS)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
LAZY_super<R|kotlin/Any|>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
super<R|C.CC|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE RAW TO BODY:
|
||||||
|
FILE: [ResolvedTo(IMPORTS)] cyclicNestedHierarchy2.kt
|
||||||
|
[ResolvedTo(BODY_RESOLVE)] annotations container
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class C : <ERROR TYPE REF: Loop in supertype: /C -> /D> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=C] constructor(): R|C| {
|
||||||
|
super<R|D|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class CC : <ERROR TYPE REF: Loop in supertype: /C.CC -> kotlin/Any> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=CC] constructor(): R|C.CC| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public open [ResolvedTo(BODY_RESOLVE)] class D : <ERROR TYPE REF: Loop in supertype: /D -> /C.CC> {
|
||||||
|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=D] constructor(): R|D| {
|
||||||
|
super<R|C.CC|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+30
@@ -84,6 +84,36 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst
|
|||||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/complexLocalHierarchy.kt");
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/complexLocalHierarchy.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy.kt")
|
||||||
|
public void testCyclicHierarchy() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy2.kt")
|
||||||
|
public void testCyclicHierarchy2() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy3.kt")
|
||||||
|
public void testCyclicHierarchy3() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicNestedHierarchy.kt")
|
||||||
|
public void testCyclicNestedHierarchy() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicNestedHierarchy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicNestedHierarchy2.kt")
|
||||||
|
public void testCyclicNestedHierarchy2() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicNestedHierarchy2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("dataClassCopy.kt")
|
@TestMetadata("dataClassCopy.kt")
|
||||||
public void testDataClassCopy() throws Exception {
|
public void testDataClassCopy() throws Exception {
|
||||||
|
|||||||
+30
@@ -84,6 +84,36 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou
|
|||||||
runTest("analysis/low-level-api-fir/testdata/lazyResolve/complexLocalHierarchy.kt");
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/complexLocalHierarchy.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy.kt")
|
||||||
|
public void testCyclicHierarchy() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy2.kt")
|
||||||
|
public void testCyclicHierarchy2() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicHierarchy3.kt")
|
||||||
|
public void testCyclicHierarchy3() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicHierarchy3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicNestedHierarchy.kt")
|
||||||
|
public void testCyclicNestedHierarchy() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicNestedHierarchy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("cyclicNestedHierarchy2.kt")
|
||||||
|
public void testCyclicNestedHierarchy2() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/lazyResolve/cyclicNestedHierarchy2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("dataClassCopy.kt")
|
@TestMetadata("dataClassCopy.kt")
|
||||||
public void testDataClassCopy() throws Exception {
|
public void testDataClassCopy() throws Exception {
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.SupertypeComputationSession
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
@@ -113,7 +115,7 @@ class FirJavaElementFinder(
|
|||||||
|
|
||||||
val superTypeRefs = when {
|
val superTypeRefs = when {
|
||||||
firClass.superTypeRefs.all { it is FirResolvedTypeRef } -> firClass.superTypeRefs
|
firClass.superTypeRefs.all { it is FirResolvedTypeRef } -> firClass.superTypeRefs
|
||||||
else -> firClass.resolveSupertypesInTheAir(session)
|
else -> firClass.resolveSupertypesOnAir(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
stub.addSupertypesReferencesLists(firClass, superTypeRefs, session)
|
stub.addSupertypesReferencesLists(firClass, superTypeRefs, session)
|
||||||
@@ -127,6 +129,13 @@ class FirJavaElementFinder(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass.resolveSupertypesOnAir(session: FirSession): List<FirTypeRef> {
|
||||||
|
val visitor = FirSupertypeResolverVisitor(session, SupertypeComputationSession(), ScopeSession())
|
||||||
|
return visitor.withFile(session.firProvider.getFirClassifierContainerFile(this.symbol)) {
|
||||||
|
visitor.resolveSpecificClassLikeSupertypes(this, superTypeRefs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirSession.collectAllDependentSourceSessions(): List<FirSession> {
|
private fun FirSession.collectAllDependentSourceSessions(): List<FirSession> {
|
||||||
val result = mutableListOf<FirSession>()
|
val result = mutableListOf<FirSession>()
|
||||||
collectAllDependentSourceSessionsTo(result)
|
collectAllDependentSourceSessionsTo(result)
|
||||||
|
|||||||
+131
-89
@@ -50,11 +50,11 @@ class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSess
|
|||||||
override val transformer = FirSupertypeResolverTransformer(session, scopeSession)
|
override val transformer = FirSupertypeResolverTransformer(session, scopeSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class FirSupertypeResolverTransformer(
|
class FirSupertypeResolverTransformer(
|
||||||
final override val session: FirSession,
|
override val session: FirSession,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession,
|
||||||
) : FirAbstractPhaseTransformer<Any?>(FirResolvePhase.SUPER_TYPES) {
|
) : FirAbstractPhaseTransformer<Any?>(FirResolvePhase.SUPER_TYPES) {
|
||||||
protected val supertypeComputationSession = SupertypeComputationSession()
|
private val supertypeComputationSession = SupertypeComputationSession()
|
||||||
|
|
||||||
private val supertypeResolverVisitor = FirSupertypeResolverVisitor(session, supertypeComputationSession, scopeSession)
|
private val supertypeResolverVisitor = FirSupertypeResolverVisitor(session, supertypeComputationSession, scopeSession)
|
||||||
private val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession, session, scopeSession)
|
private val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession, session, scopeSession)
|
||||||
@@ -97,18 +97,18 @@ fun <F : FirClassLikeDeclaration> F.runSupertypeResolvePhaseForLocalClass(
|
|||||||
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
|
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class FirApplySupertypesTransformer(
|
private class FirApplySupertypesTransformer(
|
||||||
private val supertypeComputationSession: SupertypeComputationSession,
|
private val supertypeComputationSession: SupertypeComputationSession,
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val scopeSession: ScopeSession
|
private val scopeSession: ScopeSession,
|
||||||
) : FirDefaultTransformer<Any?>() {
|
) : FirDefaultTransformer<Any?>() {
|
||||||
|
|
||||||
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
|
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
|
private fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
|
||||||
return declaration.transformChildren(this, null) as FirDeclaration
|
return declaration.transformChildren(this, data) as FirDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Any?): FirFile {
|
override fun transformFile(file: FirFile, data: Any?): FirFile {
|
||||||
@@ -200,15 +200,7 @@ private fun createOtherScopesForNestedClassesOrCompanion(
|
|||||||
// See: prepareScopes()
|
// See: prepareScopes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirTypeRef> {
|
class FirSupertypeResolverVisitor(
|
||||||
return FirSupertypeResolverVisitor(session, SupertypeComputationSession(), ScopeSession()).run {
|
|
||||||
withFile(session.firProvider.getFirClassifierContainerFile(this@resolveSupertypesInTheAir.symbol)) {
|
|
||||||
resolveSpecificClassLikeSupertypes(this@resolveSupertypesInTheAir, superTypeRefs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class FirSupertypeResolverVisitor(
|
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val supertypeComputationSession: SupertypeComputationSession,
|
private val supertypeComputationSession: SupertypeComputationSession,
|
||||||
private val scopeSession: ScopeSession,
|
private val scopeSession: ScopeSession,
|
||||||
@@ -218,11 +210,14 @@ open class FirSupertypeResolverVisitor(
|
|||||||
containingDeclarations: List<FirDeclaration> = emptyList(),
|
containingDeclarations: List<FirDeclaration> = emptyList(),
|
||||||
) : FirDefaultVisitor<Unit, Any?>() {
|
) : FirDefaultVisitor<Unit, Any?>() {
|
||||||
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
|
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
|
||||||
private val classDeclarationsStack = ArrayDeque<FirClass>()
|
|
||||||
|
@PrivateForInline
|
||||||
|
val classDeclarationsStack = ArrayDeque<FirClass>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
containingDeclarations.forEach {
|
containingDeclarations.forEach {
|
||||||
if (it is FirClass) {
|
if (it is FirClass) {
|
||||||
|
@OptIn(PrivateForInline::class)
|
||||||
classDeclarationsStack.add(it)
|
classDeclarationsStack.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,7 +275,7 @@ open class FirSupertypeResolverVisitor(
|
|||||||
private fun resolveAllSupertypes(
|
private fun resolveAllSupertypes(
|
||||||
classLikeDeclaration: FirClassLikeDeclaration,
|
classLikeDeclaration: FirClassLikeDeclaration,
|
||||||
supertypeRefs: List<FirTypeRef>,
|
supertypeRefs: List<FirTypeRef>,
|
||||||
visited: MutableSet<FirClassLikeDeclaration> = mutableSetOf()
|
visited: MutableSet<FirClassLikeDeclaration> = mutableSetOf(),
|
||||||
) {
|
) {
|
||||||
if (!visited.add(classLikeDeclaration)) return
|
if (!visited.add(classLikeDeclaration)) return
|
||||||
val supertypes: List<ConeKotlinType> =
|
val supertypes: List<ConeKotlinType> =
|
||||||
@@ -333,8 +328,8 @@ open class FirSupertypeResolverVisitor(
|
|||||||
|
|
||||||
private fun resolveSpecificClassLikeSupertypes(
|
private fun resolveSpecificClassLikeSupertypes(
|
||||||
classLikeDeclaration: FirClassLikeDeclaration,
|
classLikeDeclaration: FirClassLikeDeclaration,
|
||||||
resolveSuperTypeRefs: (FirTransformer<ScopeClassDeclaration>, ScopeClassDeclaration) -> List<FirResolvedTypeRef>
|
resolveSuperTypeRefs: (FirTransformer<ScopeClassDeclaration>, ScopeClassDeclaration) -> List<FirResolvedTypeRef>,
|
||||||
): List<FirTypeRef> {
|
): List<FirResolvedTypeRef> {
|
||||||
when (val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration)) {
|
when (val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration)) {
|
||||||
is SupertypeComputationStatus.Computed -> return status.supertypeRefs
|
is SupertypeComputationStatus.Computed -> return status.supertypeRefs
|
||||||
is SupertypeComputationStatus.Computing -> return listOf(
|
is SupertypeComputationStatus.Computing -> return listOf(
|
||||||
@@ -357,6 +352,7 @@ open class FirSupertypeResolverVisitor(
|
|||||||
else session.firProvider.getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)
|
else session.firProvider.getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)
|
||||||
|
|
||||||
val resolvedTypesRefs = transformer.withFile(newUseSiteFile) {
|
val resolvedTypesRefs = transformer.withFile(newUseSiteFile) {
|
||||||
|
@OptIn(PrivateForInline::class)
|
||||||
resolveSuperTypeRefs(
|
resolveSuperTypeRefs(
|
||||||
transformer,
|
transformer,
|
||||||
ScopeClassDeclaration(scopes, classDeclarationsStack, containerDeclaration = classLikeDeclaration),
|
ScopeClassDeclaration(scopes, classDeclarationsStack, containerDeclaration = classLikeDeclaration),
|
||||||
@@ -367,28 +363,38 @@ open class FirSupertypeResolverVisitor(
|
|||||||
return resolvedTypesRefs
|
return resolvedTypesRefs
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
private fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
||||||
declaration.acceptChildren(this, null)
|
declaration.acceptChildren(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> withClass(firClass: FirClass, body: () -> T) {
|
||||||
|
@OptIn(PrivateForInline::class)
|
||||||
|
withClassDeclarationCleanup(classDeclarationsStack, firClass) {
|
||||||
|
body()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) {
|
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?) {
|
||||||
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
|
withClass(regularClass) {
|
||||||
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
|
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
|
||||||
visitDeclarationContent(regularClass, null)
|
visitDeclarationContent(regularClass, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
|
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
|
||||||
withClassDeclarationCleanup(classDeclarationsStack, anonymousObject) {
|
withClass(anonymousObject) {
|
||||||
resolveSpecificClassLikeSupertypes(anonymousObject, anonymousObject.superTypeRefs)
|
resolveSpecificClassLikeSupertypes(anonymousObject, anonymousObject.superTypeRefs)
|
||||||
visitDeclarationContent(anonymousObject, null)
|
visitDeclarationContent(anonymousObject, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function won't call supertypeRefs on classLikeDeclaration directly
|
||||||
|
*/
|
||||||
fun resolveSpecificClassLikeSupertypes(
|
fun resolveSpecificClassLikeSupertypes(
|
||||||
classLikeDeclaration: FirClassLikeDeclaration,
|
classLikeDeclaration: FirClassLikeDeclaration,
|
||||||
supertypeRefs: List<FirTypeRef>
|
supertypeRefs: List<FirTypeRef>,
|
||||||
): List<FirTypeRef> {
|
): List<FirResolvedTypeRef> {
|
||||||
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scopeDeclaration ->
|
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scopeDeclaration ->
|
||||||
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
||||||
session.lookupTracker?.let {
|
session.lookupTracker?.let {
|
||||||
@@ -399,13 +405,8 @@ open class FirSupertypeResolverVisitor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
This list is backed by mutable list and during iterating on it we can resolve supertypes of that class via IDE light classes
|
supertypeRefs.mapTo(mutableListOf()) {
|
||||||
as IJ Java resolve may resolve a lot of stuff by light classes
|
|
||||||
this causes ConcurrentModificationException
|
|
||||||
So we create a copy of supertypeRefs to avoid it
|
|
||||||
*/
|
|
||||||
supertypeRefs.createCopy().mapTo(mutableListOf()) {
|
|
||||||
val superTypeRef = it.transform<FirTypeRef, ScopeClassDeclaration>(transformer, scopeDeclaration)
|
val superTypeRef = it.transform<FirTypeRef, ScopeClassDeclaration>(transformer, scopeDeclaration)
|
||||||
val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>()
|
val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>()
|
||||||
when {
|
when {
|
||||||
@@ -429,13 +430,11 @@ open class FirSupertypeResolverVisitor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T> List<T>.createCopy(): List<T> = ArrayList(this)
|
|
||||||
|
|
||||||
private fun addSupertypesFromExtensions(
|
private fun addSupertypesFromExtensions(
|
||||||
klass: FirClassLikeDeclaration,
|
klass: FirClassLikeDeclaration,
|
||||||
supertypeRefs: MutableList<FirResolvedTypeRef>,
|
supertypeRefs: MutableList<FirResolvedTypeRef>,
|
||||||
typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
||||||
scopeDeclaration: ScopeClassDeclaration
|
scopeDeclaration: ScopeClassDeclaration,
|
||||||
) {
|
) {
|
||||||
if (supertypeGenerationExtensions.isEmpty()) return
|
if (supertypeGenerationExtensions.isEmpty()) return
|
||||||
val typeResolveService = TypeResolveServiceForPlugins(typeResolveTransformer, scopeDeclaration)
|
val typeResolveService = TypeResolveServiceForPlugins(typeResolveTransformer, scopeDeclaration)
|
||||||
@@ -450,7 +449,7 @@ open class FirSupertypeResolverVisitor(
|
|||||||
|
|
||||||
private class TypeResolveServiceForPlugins(
|
private class TypeResolveServiceForPlugins(
|
||||||
val typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
val typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
||||||
val scopeDeclaration: ScopeClassDeclaration
|
val scopeDeclaration: ScopeClassDeclaration,
|
||||||
) : FirSupertypeGenerationExtension.TypeResolveService() {
|
) : FirSupertypeGenerationExtension.TypeResolveService() {
|
||||||
override fun resolveUserType(type: FirUserTypeRef): FirResolvedTypeRef {
|
override fun resolveUserType(type: FirUserTypeRef): FirResolvedTypeRef {
|
||||||
return type.transform(typeResolveTransformer, scopeDeclaration)
|
return type.transform(typeResolveTransformer, scopeDeclaration)
|
||||||
@@ -458,21 +457,24 @@ open class FirSupertypeResolverVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) {
|
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) {
|
||||||
|
resolveTypeAliasSupertype(typeAlias, typeAlias.expandedTypeRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveTypeAliasSupertype(typeAlias: FirTypeAlias, expandedTypeRef: FirTypeRef): List<FirResolvedTypeRef> {
|
||||||
// TODO: this if is a temporary hack for built-in types (because we can't load file for them)
|
// TODO: this if is a temporary hack for built-in types (because we can't load file for them)
|
||||||
if (typeAlias.expandedTypeRef is FirResolvedTypeRef) {
|
if (expandedTypeRef is FirResolvedTypeRef) {
|
||||||
return
|
return listOf(expandedTypeRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveSpecificClassLikeSupertypes(typeAlias) { transformer, scope ->
|
return resolveSpecificClassLikeSupertypes(typeAlias) { transformer, scope ->
|
||||||
val resolvedTypeRef =
|
val resolvedTypeRef = transformer.transformTypeRef(expandedTypeRef, scope) as? FirResolvedTypeRef
|
||||||
transformer.transformTypeRef(typeAlias.expandedTypeRef, scope) as? FirResolvedTypeRef
|
?: return@resolveSpecificClassLikeSupertypes listOf(
|
||||||
?: return@resolveSpecificClassLikeSupertypes listOf(
|
createErrorTypeRef(
|
||||||
createErrorTypeRef(
|
expandedTypeRef,
|
||||||
typeAlias.expandedTypeRef,
|
"Unresolved expanded typeRef for ${typeAlias.symbol.classId}",
|
||||||
"Unresolved expanded typeRef for ${typeAlias.symbol.classId}",
|
DiagnosticKind.UnresolvedExpandedType
|
||||||
DiagnosticKind.UnresolvedExpandedType
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fun visitNestedTypeAliases(type: TypeArgumentMarker) {
|
fun visitNestedTypeAliases(type: TypeArgumentMarker) {
|
||||||
if (type is ConeClassLikeType) {
|
if (type is ConeClassLikeType) {
|
||||||
@@ -505,11 +507,11 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
|
|||||||
diagnostic = ConeSimpleDiagnostic(message, kind)
|
diagnostic = ConeSimpleDiagnostic(message, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SupertypeComputationSession {
|
open class SupertypeComputationSession {
|
||||||
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
||||||
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||||
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
|
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||||
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
||||||
|
|
||||||
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
|
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
|
||||||
override fun forClass(firClass: FirClass, useSiteSession: FirSession): List<ConeClassLikeType> {
|
override fun forClass(firClass: FirClass, useSiteSession: FirSession): List<ConeClassLikeType> {
|
||||||
@@ -558,52 +560,77 @@ class SupertypeComputationSession {
|
|||||||
|
|
||||||
private val newClassifiersForBreakingLoops = mutableListOf<FirClassLikeDeclaration>()
|
private val newClassifiersForBreakingLoops = mutableListOf<FirClassLikeDeclaration>()
|
||||||
|
|
||||||
fun breakLoops(session: FirSession) {
|
/**
|
||||||
val visitedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
* @return **true** if class is already resolved and can't be a part of loops
|
||||||
val loopedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
*/
|
||||||
val path = mutableListOf<FirClassLikeDeclaration>()
|
protected open fun isAlreadyResolved(classLikeDeclaration: FirClassLikeDeclaration): Boolean = false
|
||||||
val pathSet = mutableSetOf<FirClassLikeDeclaration>()
|
|
||||||
|
/**
|
||||||
|
* @param supertypeRefs a collection where at least one element is [FirErrorTypeRef] for looped references
|
||||||
|
*/
|
||||||
|
protected open fun reportLoopErrorRefs(classLikeDeclaration: FirClassLikeDeclaration, supertypeRefs: List<FirResolvedTypeRef>) {
|
||||||
|
supertypeStatusMap[classLikeDeclaration] = SupertypeComputationStatus.Computed(supertypeRefs)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun getResolvedSuperTypeRefsForOutOfSessionDeclaration(
|
||||||
|
classLikeDeclaration: FirClassLikeDeclaration,
|
||||||
|
): List<FirResolvedTypeRef>? = when (classLikeDeclaration) {
|
||||||
|
is FirRegularClass -> classLikeDeclaration.superTypeRefs.filterIsInstance<FirResolvedTypeRef>()
|
||||||
|
is FirTypeAlias -> listOfNotNull(classLikeDeclaration.expandedTypeRef as? FirResolvedTypeRef)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param declaration declaration to be checked for loops
|
||||||
|
* @param visited visited declarations during the current loop search
|
||||||
|
* @param looped declarations inside loop
|
||||||
|
*/
|
||||||
|
protected fun breakLoopFor(
|
||||||
|
declaration: FirClassLikeDeclaration,
|
||||||
|
session: FirSession,
|
||||||
|
visited: MutableSet<FirClassLikeDeclaration>, // always empty for LL FIR
|
||||||
|
looped: MutableSet<FirClassLikeDeclaration>, // always empty for LL FIR
|
||||||
|
pathSet: MutableSet<FirClassLikeDeclaration>,
|
||||||
|
path: MutableList<FirClassLikeDeclaration>,
|
||||||
|
) {
|
||||||
|
require(path.isEmpty()) { "Path should be empty" }
|
||||||
|
require(pathSet.isEmpty()) { "Path set should be empty" }
|
||||||
|
|
||||||
fun checkIsInLoop(
|
fun checkIsInLoop(
|
||||||
classLikeDecl: FirClassLikeDeclaration?,
|
classLikeDeclaration: FirClassLikeDeclaration?,
|
||||||
wasSubtypingInvolved: Boolean,
|
wasSubtypingInvolved: Boolean,
|
||||||
wereTypeArgumentsInvolved: Boolean,
|
wereTypeArgumentsInvolved: Boolean,
|
||||||
) {
|
) {
|
||||||
if (classLikeDecl == null) return
|
if (classLikeDeclaration == null || isAlreadyResolved(classLikeDeclaration)) return
|
||||||
require(!wasSubtypingInvolved || !wereTypeArgumentsInvolved) {
|
require(!wasSubtypingInvolved || !wereTypeArgumentsInvolved) {
|
||||||
"This must hold by induction, because otherwise such a loop is allowed"
|
"This must hold by induction, because otherwise such a loop is allowed"
|
||||||
}
|
}
|
||||||
|
|
||||||
val supertypeRefs: List<FirResolvedTypeRef>
|
val supertypeStatus = supertypeStatusMap[classLikeDeclaration]
|
||||||
val supertypeComputationStatus = supertypeStatusMap[classLikeDecl]
|
val supertypeRefs: List<FirResolvedTypeRef> = if (supertypeStatus != null) {
|
||||||
supertypeRefs = if (supertypeComputationStatus != null) {
|
require(supertypeStatus is SupertypeComputationStatus.Computed) {
|
||||||
require(supertypeComputationStatus is SupertypeComputationStatus.Computed) {
|
"Expected computed supertypes in breakLoops for ${classLikeDeclaration.symbol.classId}"
|
||||||
"Expected computed supertypes in breakLoops for ${classLikeDecl.symbol.classId}"
|
|
||||||
}
|
}
|
||||||
supertypeComputationStatus.supertypeRefs
|
|
||||||
|
supertypeStatus.supertypeRefs
|
||||||
} else {
|
} else {
|
||||||
when (classLikeDecl) {
|
getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration) ?: return
|
||||||
is FirRegularClass ->
|
|
||||||
classLikeDecl.superTypeRefs.filterIsInstance<FirResolvedTypeRef>()
|
|
||||||
is FirTypeAlias ->
|
|
||||||
(classLikeDecl.expandedTypeRef as? FirResolvedTypeRef)?.let { listOf(it) } ?: listOf()
|
|
||||||
else -> return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classLikeDecl in visitedClassLikeDecls) {
|
if (classLikeDeclaration in visited) {
|
||||||
if (classLikeDecl in pathSet) {
|
if (classLikeDeclaration in pathSet) {
|
||||||
loopedClassLikeDecls.add(classLikeDecl)
|
looped.add(classLikeDeclaration)
|
||||||
loopedClassLikeDecls.addAll(path.takeLastWhile { element -> element != classLikeDecl })
|
looped.addAll(path.takeLastWhile { element -> element != classLikeDeclaration })
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
path.add(classLikeDecl)
|
path.add(classLikeDeclaration)
|
||||||
pathSet.add(classLikeDecl)
|
pathSet.add(classLikeDeclaration)
|
||||||
visitedClassLikeDecls.add(classLikeDecl)
|
visited.add(classLikeDeclaration)
|
||||||
|
|
||||||
val parentId = classLikeDecl.symbol.classId.relativeClassName.parent()
|
val parentId = classLikeDeclaration.symbol.classId.relativeClassName.parent()
|
||||||
if (!parentId.isRoot) {
|
if (!parentId.isRoot) {
|
||||||
val parentSymbol = session.symbolProvider.getClassLikeSymbolByClassId(ClassId.fromString(parentId.asString()))
|
val parentSymbol = session.symbolProvider.getClassLikeSymbolByClassId(ClassId.fromString(parentId.asString()))
|
||||||
if (parentSymbol is FirRegularClassSymbol) {
|
if (parentSymbol is FirRegularClassSymbol) {
|
||||||
@@ -611,14 +638,14 @@ class SupertypeComputationSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isTypeAlias = classLikeDecl is FirTypeAlias
|
val isTypeAlias = classLikeDeclaration is FirTypeAlias
|
||||||
val isSubtypingCurrentlyInvolved = !isTypeAlias
|
val isSubtypingCurrentlyInvolved = !isTypeAlias
|
||||||
|
|
||||||
// This is an optimization that prevents collecting
|
// This is an optimization that prevents collecting
|
||||||
// loops we don't want to report anyway.
|
// loops we don't want to report anyway.
|
||||||
if (wereTypeArgumentsInvolved && isSubtypingCurrentlyInvolved) {
|
if (wereTypeArgumentsInvolved && isSubtypingCurrentlyInvolved) {
|
||||||
path.removeAt(path.size - 1)
|
path.removeAt(path.size - 1)
|
||||||
pathSet.remove(classLikeDecl)
|
pathSet.remove(classLikeDeclaration)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,11 +679,11 @@ class SupertypeComputationSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resultSupertypeRefs.add(
|
resultSupertypeRefs.add(
|
||||||
if (classLikeDecl in loopedClassLikeDecls) {
|
if (classLikeDeclaration in looped) {
|
||||||
isErrorInSupertypesFound = true
|
isErrorInSupertypesFound = true
|
||||||
createErrorTypeRef(
|
createErrorTypeRef(
|
||||||
supertypeRef,
|
supertypeRef,
|
||||||
"Loop in supertype: ${classLikeDecl.symbol.classId} -> ${supertypeFir?.symbol?.classId}",
|
"Loop in supertype: ${classLikeDeclaration.symbol.classId} -> ${supertypeFir?.symbol?.classId}",
|
||||||
if (isTypeAlias) DiagnosticKind.RecursiveTypealiasExpansion else DiagnosticKind.LoopInSupertype
|
if (isTypeAlias) DiagnosticKind.RecursiveTypealiasExpansion else DiagnosticKind.LoopInSupertype
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -666,19 +693,34 @@ class SupertypeComputationSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isErrorInSupertypesFound) {
|
if (isErrorInSupertypesFound) {
|
||||||
supertypeStatusMap[classLikeDecl] = SupertypeComputationStatus.Computed(resultSupertypeRefs)
|
reportLoopErrorRefs(classLikeDeclaration, resultSupertypeRefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
path.removeAt(path.size - 1)
|
path.removeAt(path.size - 1)
|
||||||
pathSet.remove(classLikeDecl)
|
pathSet.remove(classLikeDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkIsInLoop(declaration, wasSubtypingInvolved = false, wereTypeArgumentsInvolved = false)
|
||||||
|
require(path.isEmpty()) { "Path should be empty" }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun breakLoops(session: FirSession) {
|
||||||
|
val visitedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
||||||
|
val loopedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
||||||
|
val path = mutableListOf<FirClassLikeDeclaration>()
|
||||||
|
val pathSet = mutableSetOf<FirClassLikeDeclaration>()
|
||||||
|
|
||||||
for (classifier in newClassifiersForBreakingLoops) {
|
for (classifier in newClassifiersForBreakingLoops) {
|
||||||
checkIsInLoop(classifier, wasSubtypingInvolved = false, wereTypeArgumentsInvolved = false)
|
breakLoopFor(
|
||||||
require(path.isEmpty()) {
|
declaration = classifier,
|
||||||
"Path should be empty"
|
session = session,
|
||||||
}
|
visited = visitedClassLikeDecls,
|
||||||
|
looped = loopedClassLikeDecls,
|
||||||
|
pathSet = pathSet,
|
||||||
|
path = path,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
newClassifiersForBreakingLoops.clear()
|
newClassifiersForBreakingLoops.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
// LL_FIR_DIVERGENCE
|
|
||||||
// The compiler doesn't guarantee exhaustiveness in reporting of inheritance cycles, so the compiler and LL FIR results are equally valid.
|
|
||||||
// LL_FIR_DIVERGENCE
|
|
||||||
// FILE: I.kt
|
|
||||||
|
|
||||||
open class I : <!CYCLIC_INHERITANCE_HIERARCHY!>K<!>() {
|
|
||||||
fun foo() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: J.java
|
|
||||||
|
|
||||||
class J extends I {
|
|
||||||
void bar() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: K.kt
|
|
||||||
|
|
||||||
open class K : <!EXPOSED_SUPER_CLASS!>J<!>() {
|
|
||||||
fun baz() {}
|
|
||||||
}
|
|
||||||
+3
@@ -1,3 +1,6 @@
|
|||||||
|
// LL_FIR_DIVERGENCE
|
||||||
|
// The compiler doesn't guarantee exhaustiveness in reporting of inheritance cycles, so the compiler and LL FIR results are equally valid.
|
||||||
|
// LL_FIR_DIVERGENCE
|
||||||
// FILE: ExceptionTracker.kt
|
// FILE: ExceptionTracker.kt
|
||||||
|
|
||||||
interface ExceptionTracker : <!CYCLIC_INHERITANCE_HIERARCHY!>LockBasedStorageManager.ExceptionHandlingStrategy<!> {
|
interface ExceptionTracker : <!CYCLIC_INHERITANCE_HIERARCHY!>LockBasedStorageManager.ExceptionHandlingStrategy<!> {
|
||||||
Reference in New Issue
Block a user