[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
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
override val superTypes: List<KtType> by cached {
|
||||
firSymbol.superTypesAndAnnotationsListForRegularClass(builder)
|
||||
firSymbol.superTypesList(builder)
|
||||
}
|
||||
|
||||
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.symbols.KtReceiverParameterSymbol
|
||||
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.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.declarations.resolvePhase
|
||||
|
||||
internal fun FirClassSymbol<*>.superTypesList(builder: KtSymbolByFirBuilder): List<KtType> =
|
||||
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)
|
||||
}
|
||||
internal fun FirClassSymbol<*>.superTypesList(builder: KtSymbolByFirBuilder): List<KtType> = resolvedSuperTypeRefs.mapToKtType(builder)
|
||||
|
||||
private fun List<FirTypeRef>.mapToKtType(
|
||||
builder: KtSymbolByFirBuilder,
|
||||
|
||||
+242
-189
@@ -5,36 +5,31 @@
|
||||
|
||||
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.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.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.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.FirSession
|
||||
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.render
|
||||
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.SupertypeComputationSession
|
||||
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.platformSupertypeUpdater
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
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
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
internal object LLFirSupertypeLazyResolver : LLFirLazyResolver(FirResolvePhase.SUPER_TYPES) {
|
||||
override fun resolve(
|
||||
@@ -70,14 +65,19 @@ internal object LLFirSupertypeLazyResolver : LLFirLazyResolver(FirResolvePhase.S
|
||||
}
|
||||
}
|
||||
|
||||
internal class LLFirSuperTypeTargetResolver(
|
||||
private class LLFirSuperTypeTargetResolver(
|
||||
target: LLFirResolveTarget,
|
||||
lockProvider: LLFirLockProvider,
|
||||
private val session: FirSession,
|
||||
private val scopeSession: ScopeSession,
|
||||
private val supertypeComputationSession: LLFirSupertypeComputationSession = LLFirSupertypeComputationSession(session),
|
||||
private val visitedElements: MutableSet<FirElementWithResolveState> = hashSetOf(),
|
||||
) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.SUPER_TYPES, isJumpingPhase = true) {
|
||||
|
||||
private val supertypeComputationSession = SupertypeComputationSession()
|
||||
private val supertypeResolver = FirSupertypeResolverVisitor(
|
||||
session = session,
|
||||
supertypeComputationSession = supertypeComputationSession,
|
||||
scopeSession = scopeSession,
|
||||
)
|
||||
|
||||
override fun withFile(firFile: FirFile, action: () -> Unit) {
|
||||
action()
|
||||
@@ -85,203 +85,256 @@ internal class LLFirSuperTypeTargetResolver(
|
||||
|
||||
@Deprecated("Should never be called directly, only for override purposes, please use withRegularClass", level = DeprecationLevel.ERROR)
|
||||
override fun withRegularClassImpl(firClass: FirRegularClass, action: () -> Unit) {
|
||||
doResolveWithoutLock(firClass)
|
||||
action()
|
||||
supertypeResolver.withClass(firClass) {
|
||||
doResolveWithoutLock(firClass)
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
override fun doResolveWithoutLock(target: FirElementWithResolveState): Boolean {
|
||||
val isVisited = !visitedElements.add(target)
|
||||
if (isVisited) return true
|
||||
|
||||
when (target) {
|
||||
is FirRegularClass, is FirTypeAlias -> {
|
||||
val designationToResolve = FirDesignationWithFile(nestedClassesStack, target, resolveTarget.firFile)
|
||||
val collected = collect(designationToResolve)
|
||||
supertypeComputationSession.breakLoops(session)
|
||||
apply(collected)
|
||||
}
|
||||
else -> {
|
||||
performCustomResolveUnderLock(target) {
|
||||
// just update the phase
|
||||
}
|
||||
is FirRegularClass -> performResolve(
|
||||
declaration = target,
|
||||
resolver = { target.resolveSupertypeRefs() },
|
||||
superTypeUpdater = {
|
||||
target.replaceSuperTypeRefs(it)
|
||||
session.platformSupertypeUpdater?.updateSupertypesIfNeeded(target, scopeSession)
|
||||
},
|
||||
)
|
||||
is FirTypeAlias -> performResolve(
|
||||
declaration = target,
|
||||
resolver = { target.resolveExpandedTypeRef() },
|
||||
superTypeUpdater = { target.replaceExpandedTypeRef(it.single()) },
|
||||
)
|
||||
else -> performCustomResolveUnderLock(target) {
|
||||
// just update the phase
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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,
|
||||
supertypeComputationSession = supertypeComputationSession,
|
||||
scopeSession = scopeSession,
|
||||
scopeForLocalClass = null,
|
||||
localClassesNavigationInfo = null,
|
||||
) {
|
||||
val declarationTransformer = LLFirDeclarationTransformer(classDesignation)
|
||||
visited = visited,
|
||||
looped = looped,
|
||||
pathSet = pathSet,
|
||||
path = path,
|
||||
)
|
||||
|
||||
override fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
||||
declarationTransformer.visitDeclarationContent(this, declaration, data) {
|
||||
super.visitDeclarationContent(declaration, data)
|
||||
declaration
|
||||
}
|
||||
}
|
||||
require(path.isEmpty()) { "Path should be empty" }
|
||||
require(pathSet.isEmpty()) { "Path set should be empty" }
|
||||
visited.clear()
|
||||
looped.clear()
|
||||
return updatedTypesForDeclarationsWithLoop[declaration]
|
||||
}
|
||||
|
||||
private inner class DesignatedFirApplySupertypesTransformer(classDesignation: FirDesignation) :
|
||||
FirApplySupertypesTransformer(supertypeComputationSession, session, scopeSession) {
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
override fun isAlreadyResolved(classLikeDeclaration: FirClassLikeDeclaration): Boolean {
|
||||
return !classLikeDeclaration.canHaveLoopInSupertypesHierarchy(session)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the supertypes of [designation] and collects all designations that resolved supertypes should be applied to, including
|
||||
* [designation] itself and any designations discovered via resolved supertypes.
|
||||
* We shouldn't try to iterate over unresolved class. Otherwise, it can lead to [ConcurrentModificationException]
|
||||
*/
|
||||
private fun collect(designation: FirDesignationWithFile): Collection<FirDesignationWithFile> =
|
||||
DesignationCollector().collect(designation)
|
||||
override fun getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration: FirClassLikeDeclaration): List<FirResolvedTypeRef>? {
|
||||
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>) {
|
||||
fun applyToFileSymbols(designations: List<FirDesignationWithFile>) {
|
||||
for (designation in designations) {
|
||||
checkCanceled()
|
||||
val applier = DesignatedFirApplySupertypesTransformer(designation)
|
||||
(designation.target as FirDeclaration).lazyResolveToPhase(resolverPhase.previous)
|
||||
performCustomResolveUnderLock(designation.target) {
|
||||
designation.firFile.transform<FirElement, Void?>(applier, null)
|
||||
applier.declarationTransformer.ensureDesignationPassed()
|
||||
override fun reportLoopErrorRefs(classLikeDeclaration: FirClassLikeDeclaration, supertypeRefs: List<FirResolvedTypeRef>) {
|
||||
updatedTypesForDeclarationsWithLoop.merge(classLikeDeclaration, supertypeRefs) { oldRefs, newRefs ->
|
||||
buildList<FirResolvedTypeRef>(oldRefs.size) {
|
||||
for ((old, new) in oldRefs.zip(newRefs)) {
|
||||
if (old is FirErrorTypeRef) {
|
||||
add(old)
|
||||
} else {
|
||||
add(new)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@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
|
||||
@TestMetadata("dataClassCopy.kt")
|
||||
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");
|
||||
}
|
||||
|
||||
@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
|
||||
@TestMetadata("dataClassCopy.kt")
|
||||
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.visibility
|
||||
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.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
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.types.*
|
||||
import org.jetbrains.kotlin.name.*
|
||||
@@ -113,7 +115,7 @@ class FirJavaElementFinder(
|
||||
|
||||
val superTypeRefs = when {
|
||||
firClass.superTypeRefs.all { it is FirResolvedTypeRef } -> firClass.superTypeRefs
|
||||
else -> firClass.resolveSupertypesInTheAir(session)
|
||||
else -> firClass.resolveSupertypesOnAir(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> {
|
||||
val result = mutableListOf<FirSession>()
|
||||
collectAllDependentSourceSessionsTo(result)
|
||||
|
||||
+131
-89
@@ -50,11 +50,11 @@ class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSess
|
||||
override val transformer = FirSupertypeResolverTransformer(session, scopeSession)
|
||||
}
|
||||
|
||||
open class FirSupertypeResolverTransformer(
|
||||
final override val session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
class FirSupertypeResolverTransformer(
|
||||
override val session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
) : FirAbstractPhaseTransformer<Any?>(FirResolvePhase.SUPER_TYPES) {
|
||||
protected val supertypeComputationSession = SupertypeComputationSession()
|
||||
private val supertypeComputationSession = SupertypeComputationSession()
|
||||
|
||||
private val supertypeResolverVisitor = FirSupertypeResolverVisitor(session, supertypeComputationSession, scopeSession)
|
||||
private val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession, session, scopeSession)
|
||||
@@ -97,18 +97,18 @@ fun <F : FirClassLikeDeclaration> F.runSupertypeResolvePhaseForLocalClass(
|
||||
return this.transform<F, Nothing?>(applySupertypesTransformer, null)
|
||||
}
|
||||
|
||||
open class FirApplySupertypesTransformer(
|
||||
private class FirApplySupertypesTransformer(
|
||||
private val supertypeComputationSession: SupertypeComputationSession,
|
||||
private val session: FirSession,
|
||||
private val scopeSession: ScopeSession
|
||||
private val scopeSession: ScopeSession,
|
||||
) : FirDefaultTransformer<Any?>() {
|
||||
|
||||
override fun <E : FirElement> transformElement(element: E, data: Any?): E {
|
||||
return element
|
||||
}
|
||||
|
||||
protected open fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
|
||||
return declaration.transformChildren(this, null) as FirDeclaration
|
||||
private fun transformDeclarationContent(declaration: FirDeclaration, data: Any?): FirDeclaration {
|
||||
return declaration.transformChildren(this, data) as FirDeclaration
|
||||
}
|
||||
|
||||
override fun transformFile(file: FirFile, data: Any?): FirFile {
|
||||
@@ -200,15 +200,7 @@ private fun createOtherScopesForNestedClassesOrCompanion(
|
||||
// See: prepareScopes()
|
||||
}
|
||||
|
||||
fun FirRegularClass.resolveSupertypesInTheAir(session: FirSession): List<FirTypeRef> {
|
||||
return FirSupertypeResolverVisitor(session, SupertypeComputationSession(), ScopeSession()).run {
|
||||
withFile(session.firProvider.getFirClassifierContainerFile(this@resolveSupertypesInTheAir.symbol)) {
|
||||
resolveSpecificClassLikeSupertypes(this@resolveSupertypesInTheAir, superTypeRefs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class FirSupertypeResolverVisitor(
|
||||
class FirSupertypeResolverVisitor(
|
||||
private val session: FirSession,
|
||||
private val supertypeComputationSession: SupertypeComputationSession,
|
||||
private val scopeSession: ScopeSession,
|
||||
@@ -218,11 +210,14 @@ open class FirSupertypeResolverVisitor(
|
||||
containingDeclarations: List<FirDeclaration> = emptyList(),
|
||||
) : FirDefaultVisitor<Unit, Any?>() {
|
||||
private val supertypeGenerationExtensions = session.extensionService.supertypeGenerators
|
||||
private val classDeclarationsStack = ArrayDeque<FirClass>()
|
||||
|
||||
@PrivateForInline
|
||||
val classDeclarationsStack = ArrayDeque<FirClass>()
|
||||
|
||||
init {
|
||||
containingDeclarations.forEach {
|
||||
if (it is FirClass) {
|
||||
@OptIn(PrivateForInline::class)
|
||||
classDeclarationsStack.add(it)
|
||||
}
|
||||
}
|
||||
@@ -280,7 +275,7 @@ open class FirSupertypeResolverVisitor(
|
||||
private fun resolveAllSupertypes(
|
||||
classLikeDeclaration: FirClassLikeDeclaration,
|
||||
supertypeRefs: List<FirTypeRef>,
|
||||
visited: MutableSet<FirClassLikeDeclaration> = mutableSetOf()
|
||||
visited: MutableSet<FirClassLikeDeclaration> = mutableSetOf(),
|
||||
) {
|
||||
if (!visited.add(classLikeDeclaration)) return
|
||||
val supertypes: List<ConeKotlinType> =
|
||||
@@ -333,8 +328,8 @@ open class FirSupertypeResolverVisitor(
|
||||
|
||||
private fun resolveSpecificClassLikeSupertypes(
|
||||
classLikeDeclaration: FirClassLikeDeclaration,
|
||||
resolveSuperTypeRefs: (FirTransformer<ScopeClassDeclaration>, ScopeClassDeclaration) -> List<FirResolvedTypeRef>
|
||||
): List<FirTypeRef> {
|
||||
resolveSuperTypeRefs: (FirTransformer<ScopeClassDeclaration>, ScopeClassDeclaration) -> List<FirResolvedTypeRef>,
|
||||
): List<FirResolvedTypeRef> {
|
||||
when (val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration)) {
|
||||
is SupertypeComputationStatus.Computed -> return status.supertypeRefs
|
||||
is SupertypeComputationStatus.Computing -> return listOf(
|
||||
@@ -357,6 +352,7 @@ open class FirSupertypeResolverVisitor(
|
||||
else session.firProvider.getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)
|
||||
|
||||
val resolvedTypesRefs = transformer.withFile(newUseSiteFile) {
|
||||
@OptIn(PrivateForInline::class)
|
||||
resolveSuperTypeRefs(
|
||||
transformer,
|
||||
ScopeClassDeclaration(scopes, classDeclarationsStack, containerDeclaration = classLikeDeclaration),
|
||||
@@ -367,28 +363,38 @@ open class FirSupertypeResolverVisitor(
|
||||
return resolvedTypesRefs
|
||||
}
|
||||
|
||||
open fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
||||
declaration.acceptChildren(this, null)
|
||||
private fun visitDeclarationContent(declaration: FirDeclaration, data: Any?) {
|
||||
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?) {
|
||||
withClassDeclarationCleanup(classDeclarationsStack, regularClass) {
|
||||
withClass(regularClass) {
|
||||
resolveSpecificClassLikeSupertypes(regularClass, regularClass.superTypeRefs)
|
||||
visitDeclarationContent(regularClass, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?) {
|
||||
withClassDeclarationCleanup(classDeclarationsStack, anonymousObject) {
|
||||
withClass(anonymousObject) {
|
||||
resolveSpecificClassLikeSupertypes(anonymousObject, anonymousObject.superTypeRefs)
|
||||
visitDeclarationContent(anonymousObject, null)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function won't call supertypeRefs on classLikeDeclaration directly
|
||||
*/
|
||||
fun resolveSpecificClassLikeSupertypes(
|
||||
classLikeDeclaration: FirClassLikeDeclaration,
|
||||
supertypeRefs: List<FirTypeRef>
|
||||
): List<FirTypeRef> {
|
||||
supertypeRefs: List<FirTypeRef>,
|
||||
): List<FirResolvedTypeRef> {
|
||||
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scopeDeclaration ->
|
||||
if (!classLikeDeclaration.isLocalClassOrAnonymousObject()) {
|
||||
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
|
||||
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()) {
|
||||
|
||||
supertypeRefs.mapTo(mutableListOf()) {
|
||||
val superTypeRef = it.transform<FirTypeRef, ScopeClassDeclaration>(transformer, scopeDeclaration)
|
||||
val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>()
|
||||
when {
|
||||
@@ -429,13 +430,11 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> List<T>.createCopy(): List<T> = ArrayList(this)
|
||||
|
||||
private fun addSupertypesFromExtensions(
|
||||
klass: FirClassLikeDeclaration,
|
||||
supertypeRefs: MutableList<FirResolvedTypeRef>,
|
||||
typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
||||
scopeDeclaration: ScopeClassDeclaration
|
||||
scopeDeclaration: ScopeClassDeclaration,
|
||||
) {
|
||||
if (supertypeGenerationExtensions.isEmpty()) return
|
||||
val typeResolveService = TypeResolveServiceForPlugins(typeResolveTransformer, scopeDeclaration)
|
||||
@@ -450,7 +449,7 @@ open class FirSupertypeResolverVisitor(
|
||||
|
||||
private class TypeResolveServiceForPlugins(
|
||||
val typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
|
||||
val scopeDeclaration: ScopeClassDeclaration
|
||||
val scopeDeclaration: ScopeClassDeclaration,
|
||||
) : FirSupertypeGenerationExtension.TypeResolveService() {
|
||||
override fun resolveUserType(type: FirUserTypeRef): FirResolvedTypeRef {
|
||||
return type.transform(typeResolveTransformer, scopeDeclaration)
|
||||
@@ -458,21 +457,24 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
|
||||
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)
|
||||
if (typeAlias.expandedTypeRef is FirResolvedTypeRef) {
|
||||
return
|
||||
if (expandedTypeRef is FirResolvedTypeRef) {
|
||||
return listOf(expandedTypeRef)
|
||||
}
|
||||
|
||||
resolveSpecificClassLikeSupertypes(typeAlias) { transformer, scope ->
|
||||
val resolvedTypeRef =
|
||||
transformer.transformTypeRef(typeAlias.expandedTypeRef, scope) as? FirResolvedTypeRef
|
||||
?: return@resolveSpecificClassLikeSupertypes listOf(
|
||||
createErrorTypeRef(
|
||||
typeAlias.expandedTypeRef,
|
||||
"Unresolved expanded typeRef for ${typeAlias.symbol.classId}",
|
||||
DiagnosticKind.UnresolvedExpandedType
|
||||
)
|
||||
return resolveSpecificClassLikeSupertypes(typeAlias) { transformer, scope ->
|
||||
val resolvedTypeRef = transformer.transformTypeRef(expandedTypeRef, scope) as? FirResolvedTypeRef
|
||||
?: return@resolveSpecificClassLikeSupertypes listOf(
|
||||
createErrorTypeRef(
|
||||
expandedTypeRef,
|
||||
"Unresolved expanded typeRef for ${typeAlias.symbol.classId}",
|
||||
DiagnosticKind.UnresolvedExpandedType
|
||||
)
|
||||
)
|
||||
|
||||
fun visitNestedTypeAliases(type: TypeArgumentMarker) {
|
||||
if (type is ConeClassLikeType) {
|
||||
@@ -505,11 +507,11 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
|
||||
diagnostic = ConeSimpleDiagnostic(message, kind)
|
||||
}
|
||||
|
||||
class SupertypeComputationSession {
|
||||
open class SupertypeComputationSession {
|
||||
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
||||
private val scopesForNestedClassesMap = 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() {
|
||||
override fun forClass(firClass: FirClass, useSiteSession: FirSession): List<ConeClassLikeType> {
|
||||
@@ -558,52 +560,77 @@ class SupertypeComputationSession {
|
||||
|
||||
private val newClassifiersForBreakingLoops = mutableListOf<FirClassLikeDeclaration>()
|
||||
|
||||
fun breakLoops(session: FirSession) {
|
||||
val visitedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
||||
val loopedClassLikeDecls = mutableSetOf<FirClassLikeDeclaration>()
|
||||
val path = mutableListOf<FirClassLikeDeclaration>()
|
||||
val pathSet = mutableSetOf<FirClassLikeDeclaration>()
|
||||
/**
|
||||
* @return **true** if class is already resolved and can't be a part of loops
|
||||
*/
|
||||
protected open fun isAlreadyResolved(classLikeDeclaration: FirClassLikeDeclaration): Boolean = false
|
||||
|
||||
/**
|
||||
* @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(
|
||||
classLikeDecl: FirClassLikeDeclaration?,
|
||||
classLikeDeclaration: FirClassLikeDeclaration?,
|
||||
wasSubtypingInvolved: Boolean,
|
||||
wereTypeArgumentsInvolved: Boolean,
|
||||
) {
|
||||
if (classLikeDecl == null) return
|
||||
if (classLikeDeclaration == null || isAlreadyResolved(classLikeDeclaration)) return
|
||||
require(!wasSubtypingInvolved || !wereTypeArgumentsInvolved) {
|
||||
"This must hold by induction, because otherwise such a loop is allowed"
|
||||
}
|
||||
|
||||
val supertypeRefs: List<FirResolvedTypeRef>
|
||||
val supertypeComputationStatus = supertypeStatusMap[classLikeDecl]
|
||||
supertypeRefs = if (supertypeComputationStatus != null) {
|
||||
require(supertypeComputationStatus is SupertypeComputationStatus.Computed) {
|
||||
"Expected computed supertypes in breakLoops for ${classLikeDecl.symbol.classId}"
|
||||
val supertypeStatus = supertypeStatusMap[classLikeDeclaration]
|
||||
val supertypeRefs: List<FirResolvedTypeRef> = if (supertypeStatus != null) {
|
||||
require(supertypeStatus is SupertypeComputationStatus.Computed) {
|
||||
"Expected computed supertypes in breakLoops for ${classLikeDeclaration.symbol.classId}"
|
||||
}
|
||||
supertypeComputationStatus.supertypeRefs
|
||||
|
||||
supertypeStatus.supertypeRefs
|
||||
} else {
|
||||
when (classLikeDecl) {
|
||||
is FirRegularClass ->
|
||||
classLikeDecl.superTypeRefs.filterIsInstance<FirResolvedTypeRef>()
|
||||
is FirTypeAlias ->
|
||||
(classLikeDecl.expandedTypeRef as? FirResolvedTypeRef)?.let { listOf(it) } ?: listOf()
|
||||
else -> return
|
||||
}
|
||||
getResolvedSuperTypeRefsForOutOfSessionDeclaration(classLikeDeclaration) ?: return
|
||||
}
|
||||
|
||||
if (classLikeDecl in visitedClassLikeDecls) {
|
||||
if (classLikeDecl in pathSet) {
|
||||
loopedClassLikeDecls.add(classLikeDecl)
|
||||
loopedClassLikeDecls.addAll(path.takeLastWhile { element -> element != classLikeDecl })
|
||||
if (classLikeDeclaration in visited) {
|
||||
if (classLikeDeclaration in pathSet) {
|
||||
looped.add(classLikeDeclaration)
|
||||
looped.addAll(path.takeLastWhile { element -> element != classLikeDeclaration })
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
path.add(classLikeDecl)
|
||||
pathSet.add(classLikeDecl)
|
||||
visitedClassLikeDecls.add(classLikeDecl)
|
||||
path.add(classLikeDeclaration)
|
||||
pathSet.add(classLikeDeclaration)
|
||||
visited.add(classLikeDeclaration)
|
||||
|
||||
val parentId = classLikeDecl.symbol.classId.relativeClassName.parent()
|
||||
val parentId = classLikeDeclaration.symbol.classId.relativeClassName.parent()
|
||||
if (!parentId.isRoot) {
|
||||
val parentSymbol = session.symbolProvider.getClassLikeSymbolByClassId(ClassId.fromString(parentId.asString()))
|
||||
if (parentSymbol is FirRegularClassSymbol) {
|
||||
@@ -611,14 +638,14 @@ class SupertypeComputationSession {
|
||||
}
|
||||
}
|
||||
|
||||
val isTypeAlias = classLikeDecl is FirTypeAlias
|
||||
val isTypeAlias = classLikeDeclaration is FirTypeAlias
|
||||
val isSubtypingCurrentlyInvolved = !isTypeAlias
|
||||
|
||||
// This is an optimization that prevents collecting
|
||||
// loops we don't want to report anyway.
|
||||
if (wereTypeArgumentsInvolved && isSubtypingCurrentlyInvolved) {
|
||||
path.removeAt(path.size - 1)
|
||||
pathSet.remove(classLikeDecl)
|
||||
pathSet.remove(classLikeDeclaration)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -652,11 +679,11 @@ class SupertypeComputationSession {
|
||||
}
|
||||
|
||||
resultSupertypeRefs.add(
|
||||
if (classLikeDecl in loopedClassLikeDecls) {
|
||||
if (classLikeDeclaration in looped) {
|
||||
isErrorInSupertypesFound = true
|
||||
createErrorTypeRef(
|
||||
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
|
||||
)
|
||||
} else {
|
||||
@@ -666,19 +693,34 @@ class SupertypeComputationSession {
|
||||
}
|
||||
|
||||
if (isErrorInSupertypesFound) {
|
||||
supertypeStatusMap[classLikeDecl] = SupertypeComputationStatus.Computed(resultSupertypeRefs)
|
||||
reportLoopErrorRefs(classLikeDeclaration, resultSupertypeRefs)
|
||||
}
|
||||
|
||||
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) {
|
||||
checkIsInLoop(classifier, wasSubtypingInvolved = false, wereTypeArgumentsInvolved = false)
|
||||
require(path.isEmpty()) {
|
||||
"Path should be empty"
|
||||
}
|
||||
breakLoopFor(
|
||||
declaration = classifier,
|
||||
session = session,
|
||||
visited = visitedClassLikeDecls,
|
||||
looped = loopedClassLikeDecls,
|
||||
pathSet = pathSet,
|
||||
path = path,
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
interface ExceptionTracker : <!CYCLIC_INHERITANCE_HIERARCHY!>LockBasedStorageManager.ExceptionHandlingStrategy<!> {
|
||||
Reference in New Issue
Block a user