diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt index 806c9df2f3f..067e8ce3650 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/qualifiers/UsualClassTypeQualifierBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -7,22 +7,21 @@ package org.jetbrains.kotlin.analysis.api.fir.types.qualifiers import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.toSequence import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries -import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry -import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment import org.jetbrains.kotlin.fir.containingClassForLocal import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry +import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment -import org.jetbrains.kotlin.utils.exceptions.withPsiEntry internal object UsualClassTypeQualifierBuilder { fun buildQualifiers( @@ -48,23 +47,18 @@ internal object UsualClassTypeQualifierBuilder { val designation = classSymbolToRender.fir.let { val nonLocalDesignation = it.tryCollectDesignation() - nonLocalDesignation?.toSequence(includeTarget = true)?.toList() - ?: collectDesignationPathForLocal(it) - } - + nonLocalDesignation?.toSequence(includeTarget = true)?.toList() ?: collectDesignationPathForLocal(it) + }.filterIsInstance() var typeParametersLeft = coneType.typeArguments.size fun needToRenderTypeParameters(index: Int): Boolean { if (typeParametersLeft <= 0) return false - return index == designation.lastIndex || - (designation[index] as? FirRegularClass)?.isInner == true || - (designation[index + 1] as? FirRegularClass)?.isInner == true + return index == designation.lastIndex || designation[index].isInner || designation[index + 1].isInner } val result = mutableListOf() designation.forEachIndexed { index, currentClass -> - check(currentClass is FirRegularClass) val typeParameters = if (needToRenderTypeParameters(index)) { val typeParametersCount = currentClass.typeParameters.count { it is FirTypeParameter } val begin = typeParametersLeft - typeParametersCount @@ -95,7 +89,7 @@ internal object UsualClassTypeQualifierBuilder { return designation.asReversed() } - private fun collectDesignationPathForLocal(declaration: FirClassLikeDeclaration): List { + private fun collectDesignationPathForLocal(declaration: FirClassLikeDeclaration): List { checkWithAttachment( declaration.isLocal, message = { "${declaration::class} is not local" } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirDesignationState.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirDesignationState.kt index 183c699de36..ad876f4b695 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirDesignationState.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/FirDesignationState.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -42,15 +42,14 @@ private class FirDesignationState(val designation: FirDesignation) { * Holds current declaration index * if `currentIndex in [0, designation.path.lastIndex]` then current declaration is in path * if `currentIndex == `designation.path.lastIndex + 1` then current declaration is our target declaration - * if `currentIndex > designation.path.lastIndex + 1` then we are inside current declaration + * if `currentIndex > designation.path.lastIndex + 1` then we are inside target declaration */ private var currentIndex = -1 fun canGoNext(): Boolean = currentIndex < designation.path.size val currentDeclarationIfPresent: FirElementWithResolveState? - get() = when (currentIndex) { - in designation.path.indices -> designation.path[currentIndex] + get() = designation.path.getOrNull(currentIndex) ?: when (currentIndex) { designation.path.size -> designation.target else -> null } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt index e106a9b5d59..7942d79e734 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -33,38 +33,101 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.utils.exceptions.ExceptionAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment -class FirDesignationWithFile( - path: List, - target: FirElementWithResolveState, - val firFile: FirFile -) : FirDesignation( - path, - target, +/** + * This class describes where locates [target] element and its essential [path]. + * + * Usually a resolver uses [path] to resolve [target] in the proper context. + * + * @see org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget + */ +class FirDesignation( + /** + * The path to [target] element. + * + * ### Contracts: + * * Can contain [FirFile] only in the first position + * * Can contain [FirScript] only in the first or second position + * + * @see file + * @see fileOrNull + * @see script + * @see scriptOrNull + */ + val path: List, + val target: FirElementWithResolveState, ) { - fun toSequenceWithFile(includeTarget: Boolean): Sequence = sequence { - yield(firFile) - yieldAll(path) - if (includeTarget) yield(target) + init { + for ((index, declaration) in path.withIndex()) { + when (declaration) { + is FirFile -> requireWithAttachment( + index == 0, + { "${FirFile::class.simpleName} can be only in the first position of the path, but actual is '$index'" }, + ) { + withFirDesignationEntry("designation", this@FirDesignation) + } + + is FirScript -> requireWithAttachment( + index == 0 || index == 1 && path.first() is FirFile, + { "${FirScript::class.simpleName} can be only in the first or second position of the path, but actual is '$index'" }, + ) { + withFirDesignationEntry("designation", this@FirDesignation) + } + + is FirRegularClass -> {} + else -> errorWithAttachment("Unexpected declaration type: ${declaration::class.simpleName}") { + withFirDesignationEntry("designation", this@FirDesignation) + } + } + } + } + + val file: FirFile + get() = fileOrNull ?: errorWithAttachment("File is not found") { + withFirDesignationEntry("designation", this@FirDesignation) + } + + val fileOrNull: FirFile? get() = path.firstOrNull() as? FirFile + + val script: FirScript + get() = scriptOrNull ?: errorWithAttachment("Script is not found") { + withFirDesignationEntry("designation", this@FirDesignation) + } + + val scriptOrNull: FirScript? get() = path.getOrNull(0) as? FirScript ?: path.getOrNull(1) as? FirScript + + /** + * This property exists only for compatibility and should be dropped after KT-65345 + */ + val classPath: List get() = path.filterIsInstance() + + /** + * This constructor exists only for compatibility and should be dropped after KT-65345 + */ + constructor( + firFile: FirFile, + path: List, + target: FirElementWithResolveState, + ) : this(listOf(firFile) + path, target) +} + +fun ExceptionAttachmentBuilder.withFirDesignationEntry(name: String, designation: FirDesignation) { + withEntryGroup(name) { + for ((index, declaration) in designation.path.withIndex()) { + withFirEntry("path$index", declaration) + } + + withFirEntry("target", designation.target) } } -class FirDesignationWithScript( - path: List, - target: FirElementWithResolveState, - val firScript: FirScript, -): FirDesignation(path, target) - -open class FirDesignation( - val path: List, - val target: FirElementWithResolveState, -) { - fun toSequence(includeTarget: Boolean): Sequence = sequence { - yieldAll(path) - if (includeTarget) yield(target) - } +fun FirDesignation.toSequence(includeTarget: Boolean): Sequence = sequence { + yieldAll(path) + if (includeTarget) yield(target) } private fun collectDesignationPath(target: FirElementWithResolveState): List? { @@ -247,7 +310,7 @@ private fun findKotlinStdlibClass(classId: ClassId, target: FirDeclaration): Fir return FirElementFinder.findClassifierWithClassId(firFile, classId) as? FirRegularClass } -fun FirElementWithResolveState.collectDesignation(firFile: FirFile): FirDesignationWithFile = +fun FirElementWithResolveState.collectDesignation(firFile: FirFile): FirDesignation = tryCollectDesignation(firFile) ?: errorWithAttachment("No designation of local declaration") { withFirEntry("firFile", firFile) } @@ -258,15 +321,15 @@ fun FirElementWithResolveState.collectDesignation(): FirDesignation = withFirEntry("FirDeclaration", this@collectDesignation) } -fun FirElementWithResolveState.collectDesignationWithFile(): FirDesignationWithFile = +fun FirElementWithResolveState.collectDesignationWithFile(): FirDesignation = tryCollectDesignationWithFile() ?: errorWithAttachment("No designation of local declaration") { withFirEntry("FirDeclaration", this@collectDesignationWithFile) } -fun FirElementWithResolveState.tryCollectDesignation(firFile: FirFile): FirDesignationWithFile? = +fun FirElementWithResolveState.tryCollectDesignation(firFile: FirFile): FirDesignation? = collectDesignationPath(this)?.let { - FirDesignationWithFile(it, this, firFile) + FirDesignation(firFile, it, this) } fun FirElementWithResolveState.tryCollectDesignation(): FirDesignation? = @@ -274,11 +337,11 @@ fun FirElementWithResolveState.tryCollectDesignation(): FirDesignation? = FirDesignation(it, this) } -fun FirElementWithResolveState.tryCollectDesignationWithFile(): FirDesignationWithFile? { +fun FirElementWithResolveState.tryCollectDesignationWithFile(): FirDesignation? { return when (this) { is FirScript, is FirCodeFragment, is FirFileAnnotationsContainer -> { val firFile = getContainingFile() ?: return null - FirDesignationWithFile(path = emptyList(), this, firFile) + FirDesignation(firFile, path = emptyList(), this) } is FirSyntheticProperty, is FirSyntheticPropertyAccessor -> unexpectedElementError(this) @@ -288,24 +351,24 @@ fun FirElementWithResolveState.tryCollectDesignationWithFile(): FirDesignationWi val path = collectDesignationPath(this) ?: return null val firFile = path.lastOrNull()?.getContainingFile() ?: getContainingFile() ?: return null - FirDesignationWithFile(path, this, firFile) + FirDesignation(firFile, path, this) } else -> unexpectedElementError(this) } } -private fun FirDeclaration.scriptDesignation(): FirDesignationWithFile? { +private fun FirDeclaration.scriptDesignation(): FirDesignation? { return when { this is FirAnonymousInitializer -> { val firScriptSymbol = (containingDeclarationSymbol as? FirScriptSymbol) ?: return null val firFile = firScriptSymbol.fir.getContainingFile() ?: return null - FirDesignationWithFile(path = emptyList(), firScriptSymbol.fir, firFile) + FirDesignation(firFile, path = emptyList(), firScriptSymbol.fir) } isScriptDependentDeclaration -> { val firFile = getContainingFile() ?: return null val firScript = firFile.declarations.singleOrNull() as? FirScript ?: return null - FirDesignationWithFile(path = emptyList(), firScript, firFile) + FirDesignation(firFile, path = emptyList(), firScript) } else -> null } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/targets/targetUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/targets/targetUtils.kt index df9d1ce0db4..6de74db1303 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/targets/targetUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/targets/targetUtils.kt @@ -1,24 +1,22 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession -import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment -internal fun LLFirResolveTarget.forEachPathElementAndTarget(action: (FirElementWithResolveState) -> Unit) { - path.forEach(action) - forEachTarget(action) -} - -internal fun FirDesignationWithFile.asResolveTarget(): LLFirSingleResolveTarget = LLFirSingleResolveTarget(firFile, path, target) +internal fun FirDesignation.asResolveTarget(): LLFirSingleResolveTarget = LLFirSingleResolveTarget( + file, + classPath, + target, +) /** * Resolves the target to the specified [phase]. diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt index ab5c287e642..0da1810dc95 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt @@ -1,13 +1,14 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir import org.jetbrains.kotlin.analysis.low.level.api.fir.ContextByDesignationCollector -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.withFirDesignationEntry import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClassIdOrNull import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElementWithResolveState @@ -23,7 +24,7 @@ import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment private class ContextCollectingDiagnosticCollectorVisitor private constructor( sessionHolder: SessionHolder, - designation: FirDesignationWithFile, + designation: FirDesignation, ) : AbstractDiagnosticCollectorVisitor( PersistentCheckerContextFactory.createEmptyPersistenceCheckerContext(sessionHolder) ) { @@ -45,11 +46,20 @@ private class ContextCollectingDiagnosticCollectorVisitor private constructor( override fun checkElement(element: FirElement) {} + fun collect(): CheckerContextForProvider { + // Trigger the collector + contextCollector.nextStep() + + return contextCollector.getCollectedContext() + } + companion object { - fun collect(sessionHolder: SessionHolder, designation: FirDesignationWithFile): CheckerContextForProvider { - val visitor = ContextCollectingDiagnosticCollectorVisitor(sessionHolder, designation) - designation.firFile.accept(visitor, null) - return visitor.contextCollector.getCollectedContext() + fun collect(sessionHolder: SessionHolder, designation: FirDesignation): CheckerContextForProvider { + requireWithAttachment(designation.fileOrNull != null, { "${FirFile::class.simpleName} is missed" }) { + withFirDesignationEntry("designation", designation) + } + + return ContextCollectingDiagnosticCollectorVisitor(sessionHolder, designation).collect() } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt index 2a9b56bbc1d..52186c4704d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileElementFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -9,9 +9,9 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignationWithFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithSpecificMembersResolveTarget +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.resolve import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.isImplicitConstructor import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor internal object FileElementFactory { fun createFileStructureElement( @@ -20,7 +20,7 @@ internal object FileElementFactory { moduleComponents: LLFirModuleResolveComponents, ): FileStructureElement = when { firDeclaration is FirRegularClass -> { - lazyResolveClassWithGeneratedMembers(firDeclaration, moduleComponents) + lazyResolveClassWithGeneratedMembers(firDeclaration) ClassDeclarationStructureElement(firFile, firDeclaration, moduleComponents) } @@ -28,7 +28,7 @@ internal object FileElementFactory { else -> DeclarationStructureElement(firFile, firDeclaration, moduleComponents) } - private fun lazyResolveClassWithGeneratedMembers(firClass: FirRegularClass, moduleComponents: LLFirModuleResolveComponents) { + private fun lazyResolveClassWithGeneratedMembers(firClass: FirRegularClass) { val classMembersToResolve = buildList { for (member in firClass.declarations) { when { @@ -57,16 +57,12 @@ internal object FileElementFactory { val firClassDesignation = firClass.collectDesignationWithFile() val designationWithMembers = LLFirClassWithSpecificMembersResolveTarget( - firClassDesignation.firFile, - firClassDesignation.path, + firClassDesignation.file, + firClassDesignation.classPath, firClass, classMembersToResolve, ) - moduleComponents.firModuleLazyDeclarationResolver.lazyResolveTarget( - designationWithMembers, - FirResolvePhase.BODY_RESOLVE, - towerDataContextCollector = null - ) + designationWithMembers.resolve(FirResolvePhase.BODY_RESOLVE) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt index 74c019a126c..f5d4775daf3 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -46,7 +46,7 @@ import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment internal object FirLazyBodiesCalculator { fun calculateBodies(designation: FirDesignation) { - designation.target.transform>( + designation.target.transformSingle( FirTargetLazyBodiesCalculatorTransformer, designation.path.toPersistentList(), ) @@ -85,8 +85,10 @@ internal object FirLazyBodiesCalculator { return newAnnotationCall.argumentList } - fun createDeclarationsForScript(script: FirScript): List { - val newScript = revive(FirDesignation(emptyList(), script)) + fun createDeclarationsForScript(designation: FirDesignation): List { + designation.target as FirScript + + val newScript = revive(designation) return newScript.declarations } @@ -747,7 +749,7 @@ private abstract class FirLazyAnnotationTransformer : FirTransformer): FirFile { + override fun transformFile(file: FirFile, data: PersistentList): FirFile { file.declarations.forEach { it.transformSingle(this, data) } @@ -755,7 +757,7 @@ private object FirAllLazyBodiesCalculatorTransformer : FirLazyBodiesCalculatorTr return file } - override fun transformElement(element: E, data: PersistentList): E { + override fun transformElement(element: E, data: PersistentList): E { if (element is FirRegularClass) { val newList = data.add(element) element.declarations.forEach { @@ -770,10 +772,10 @@ private object FirAllLazyBodiesCalculatorTransformer : FirLazyBodiesCalculatorTr private object FirTargetLazyBodiesCalculatorTransformer : FirLazyBodiesCalculatorTransformer() -private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer>() { - override fun transformElement(element: E, data: PersistentList): E = element +private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer>() { + override fun transformElement(element: E, data: PersistentList): E = element - override fun transformField(field: FirField, data: PersistentList): FirStatement { + override fun transformField(field: FirField, data: PersistentList): FirStatement { if (field.initializer is FirLazyExpression) { val designation = FirDesignation(data, field) calculateLazyBodiesForField(designation) @@ -784,7 +786,7 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer, + data: PersistentList, ): FirSimpleFunction { if (needCalculatingLazyBodyForFunction(simpleFunction)) { val designation = FirDesignation(data, simpleFunction) @@ -796,7 +798,7 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer, + data: PersistentList, ): FirConstructor { if (needCalculatingLazyBodyForConstructor(constructor)) { val designation = FirDesignation(data, constructor) @@ -808,10 +810,10 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer, + data: PersistentList, ) = transformConstructor(errorPrimaryConstructor, data) - override fun transformProperty(property: FirProperty, data: PersistentList): FirProperty { + override fun transformProperty(property: FirProperty, data: PersistentList): FirProperty { if (needCalculatingLazyBodyForProperty(property)) { val designation = FirDesignation(data, property) calculateLazyBodyForProperty(designation) @@ -820,11 +822,11 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer): FirStatement { + override fun transformPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: PersistentList): FirStatement { return propertyAccessor.also { transformProperty(it.propertySymbol.fir, data) } } - override fun transformEnumEntry(enumEntry: FirEnumEntry, data: PersistentList): FirStatement { + override fun transformEnumEntry(enumEntry: FirEnumEntry, data: PersistentList): FirStatement { if (enumEntry.initializer is FirLazyExpression) { val designation = FirDesignation(data, enumEntry) calculateLazyInitializerForEnumEntry(designation) @@ -834,7 +836,7 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer, + anonymousInitializer: FirAnonymousInitializer, data: PersistentList, ): FirAnonymousInitializer { if (anonymousInitializer.body is FirLazyBlock) { val designation = FirDesignation(data, anonymousInitializer) @@ -844,7 +846,7 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer): FirCodeFragment { + override fun transformCodeFragment(codeFragment: FirCodeFragment, data: PersistentList): FirCodeFragment { if (codeFragment.block is FirLazyBlock) { val designation = FirDesignation(data, codeFragment) calculateLazyBodyForCodeFragment(designation) @@ -853,7 +855,7 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer): FirScript { + override fun transformScript(script: FirScript, data: PersistentList): FirScript { for (declaration in script.declarations) { if (declaration !is FirAnonymousInitializer) continue declaration.accept(this, data) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt index 93d210e8130..e88bf0ca470 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveMultiDesignationCollector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -29,7 +29,7 @@ internal object LLFirResolveMultiDesignationCollector { fun getDesignationsToResolveWithCallableMembers(target: FirRegularClass): List { val designation = target.tryCollectDesignationWithFile() ?: return emptyList() - val resolveTarget = LLFirClassWithAllCallablesResolveTarget(designation.firFile, designation.path, target) + val resolveTarget = LLFirClassWithAllCallablesResolveTarget(designation.file, designation.classPath, target) return listOf(resolveTarget) } @@ -42,7 +42,7 @@ internal object LLFirResolveMultiDesignationCollector { } val designation = target.tryCollectDesignationWithFile() ?: return emptyList() - val resolveTarget = LLFirWholeElementResolveTarget(designation.firFile, designation.path, target) + val resolveTarget = LLFirWholeElementResolveTarget(designation.file, designation.classPath, target) return listOf(resolveTarget) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index e4f262023fb..2b396f218cc 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -105,7 +105,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( builder.context.forcedContainerSymbol = designation.target.symbol } - return builder.moveNext(designation.path.iterator(), containingClass = null) + return builder.moveNext(designation.classPath.iterator(), containingClass = null) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt index 722dcdc1e16..4e792d3b151 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirBodyLazyResolver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -358,7 +358,7 @@ internal object BodyStateKeepers { lastProperty.bodyResolveState != FirPropertyBodyResolveState.ALL_BODIES_RESOLVED ) { add(RESULT_PROPERTY, designation) - val recreatedDeclarations = FirLazyBodiesCalculator.createDeclarationsForScript(script) + val recreatedDeclarations = FirLazyBodiesCalculator.createDeclarationsForScript(designation) requireSameSize(oldDeclarations, recreatedDeclarations) lastProperty.replaceInitializer((recreatedDeclarations.last() as FirProperty).initializer) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/ContextCollector.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/ContextCollector.kt index 7f60b482688..ee0e15e3487 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/ContextCollector.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/ContextCollector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -8,11 +8,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util import com.intellij.openapi.progress.ProgressManager import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithScript import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.isAutonomousDeclaration -import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector.ContextKind import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector.Context +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector.ContextKind import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ContextCollector.FilterResponse import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession @@ -42,7 +41,6 @@ import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.util.PrivateForInline -import org.jetbrains.kotlin.utils.yieldIfNotNull import java.util.ArrayList object ContextCollector { @@ -126,11 +124,10 @@ object ContextCollector { val designationPath = FirElementFinder.collectDesignationPath(file, contextKtDeclaration) if (designationPath != null) { val script = file.declarations.singleOrNull() as? FirScript - return if (script == null || script === designationPath.target) { FirDesignation(designationPath.path, designationPath.target) } else { - FirDesignationWithScript(designationPath.path, designationPath.target, script) + FirDesignation(listOf(script) + designationPath.path, designationPath.target) } } } @@ -177,7 +174,6 @@ object ContextCollector { private class DesignationInterceptor(private val designation: FirDesignation) : () -> FirElement? { private val targetIterator = iterator { - yieldIfNotNull((designation as? FirDesignationWithScript)?.firScript) yieldAll(designation.path) yield(designation.target) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firDeclarationDesignationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firDeclarationDesignationUtils.kt index a74d1855294..558d99642d7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firDeclarationDesignationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/firDeclarationDesignationUtils.kt @@ -1,20 +1,15 @@ /* - * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.analysis.low.level.api.fir.util -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation -import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment import org.jetbrains.kotlin.fir.FirElementWithResolveState -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration -import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess -import org.jetbrains.kotlin.fir.declarations.resolvePhase import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry +import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment internal fun FirElementWithResolveState.checkPhase(requiredResolvePhase: FirResolvePhase) { @OptIn(ResolveStateAccess::class) @@ -26,27 +21,3 @@ internal fun FirElementWithResolveState.checkPhase(requiredResolvePhase: FirReso withFirEntry("firDeclaration", this@checkPhase) } } - -internal fun FirDesignation.checkPathPhase(firResolvePhase: FirResolvePhase) = - path.forEach { it.checkPhase(firResolvePhase) } - -internal fun FirDesignation.checkDesignationPhase(firResolvePhase: FirResolvePhase) { - checkPathPhase(firResolvePhase) - target.checkPhase(firResolvePhase) -} - -internal fun FirDesignation.checkDesignationPhaseForClasses(firResolvePhase: FirResolvePhase) { - checkPathPhase(firResolvePhase) - if (target is FirClassLikeDeclaration) { - @OptIn(ResolveStateAccess::class) - val resolveState = target.resolveState - check(resolveState.resolvePhase >= firResolvePhase) { - "Expected $firResolvePhase but found $resolveState" - } - } -} - -internal fun FirDesignation.isTargetCallableDeclarationAndInPhase(firResolvePhase: FirResolvePhase): Boolean = - (target as? FirCallableDeclaration)?.let { it.resolvePhase >= firResolvePhase } ?: false - -internal fun FirDesignation.targetContainingDeclaration(): FirDeclaration? = path.lastOrNull()