[LL FIR] simplify FileStructureElement invalidation

We can avoid complex reanalyze-base logic and just directly
drop outdated data from FileStructureCache

^KT-60611
This commit is contained in:
Dmitrii Gridin
2023-08-31 23:01:56 +02:00
committed by Space Team
parent 89c186c496
commit 8832865e9a
88 changed files with 370 additions and 507 deletions
@@ -6,9 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents 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.collectDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithSpecificMembersResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithSpecificMembersResolveTarget
@@ -22,48 +20,16 @@ import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
internal object FileElementFactory { internal object FileElementFactory {
fun createFileStructureElement( fun createFileStructureElement(
firDeclaration: FirDeclaration, firDeclaration: FirDeclaration,
ktDeclaration: KtDeclaration,
firFile: FirFile, firFile: FirFile,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
): FileStructureElement = when { ): FileStructureElement = when {
ktDeclaration is KtNamedFunction && ktDeclaration.isReanalyzableContainer() -> ReanalyzableFunctionStructureElement( firDeclaration is FirRegularClass -> {
firFile, lazyResolveClassWithGeneratedMembers(firDeclaration, moduleComponents)
ktDeclaration, ClassDeclarationStructureElement(firFile, firDeclaration, moduleComponents)
(firDeclaration as FirSimpleFunction).symbol,
ktDeclaration.modificationStamp,
moduleComponents,
)
ktDeclaration is KtProperty &&
(ktDeclaration.isReanalyzableContainer() || ktDeclaration.accessors.any { it.isReanalyzableContainer() })
-> ReanalyzablePropertyStructureElement(
firFile,
ktDeclaration,
(firDeclaration as FirProperty).symbol,
ktDeclaration.modificationStamp,
moduleComponents,
)
ktDeclaration is KtClassOrObject && ktDeclaration !is KtEnumEntry -> {
lazyResolveClassWithGeneratedMembers(firDeclaration as FirRegularClass, moduleComponents)
NonReanalyzableClassDeclarationStructureElement(
firFile,
firDeclaration,
ktDeclaration,
moduleComponents,
)
} }
ktDeclaration is KtScript -> RootScriptStructureElement(firFile, firDeclaration as FirScript, ktDeclaration, moduleComponents) firDeclaration is FirScript -> RootScriptStructureElement(firFile, firDeclaration, moduleComponents)
else -> DeclarationStructureElement(firFile, firDeclaration, moduleComponents)
else -> {
NonReanalyzableNonClassDeclarationStructureElement(
firFile,
firDeclaration,
ktDeclaration,
moduleComponents,
)
}
} }
private fun lazyResolveClassWithGeneratedMembers(firClass: FirRegularClass, moduleComponents: LLFirModuleResolveComponents) { private fun lazyResolveClassWithGeneratedMembers(firClass: FirRegularClass, moduleComponents: LLFirModuleResolveComponents) {
@@ -149,14 +115,6 @@ private fun isInsideContract(body: KtExpression, child: PsiElement): Boolean {
return firstStatement.isAncestor(child) return firstStatement.isAncestor(child)
} }
@TestOnly
internal fun KtDeclaration.isReanalyzableContainer(): Boolean = when (this) {
is KtNamedFunction -> isReanalyzableContainer()
is KtPropertyAccessor -> isReanalyzableContainer()
is KtProperty -> isReanalyzableContainer()
else -> error("Unknown declaration type: ${this::class.simpleName}")
}
private fun KtNamedFunction.isReanalyzableContainer(): Boolean = hasBlockBody() || typeReference != null private fun KtNamedFunction.isReanalyzableContainer(): Boolean = hasBlockBody() || typeReference != null
private fun KtPropertyAccessor.isReanalyzableContainer(): Boolean = isSetter || hasBlockBody() || property.typeReference != null private fun KtPropertyAccessor.isReanalyzableContainer(): Boolean = isSetter || hasBlockBody() || property.typeReference != null
@@ -10,25 +10,25 @@ import com.intellij.psi.PsiErrorElement
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.canBePartOfParentDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceByTraversingWholeTree import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceByTraversingWholeTree
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.canBePartOfParentDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment
import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
import java.util.concurrent.ConcurrentHashMap
internal class FileStructure private constructor( internal class FileStructure private constructor(
private val ktFile: KtFile, private val ktFile: KtFile,
@@ -49,7 +49,24 @@ internal class FileStructure private constructor(
private val structureElements = ConcurrentHashMap<KtElement, FileStructureElement>() private val structureElements = ConcurrentHashMap<KtElement, FileStructureElement>()
/**
* Must be called only under write-lock.
*
* This method is responsible for "invalidation" of re-analyzable declarations.
*
* @see LLFirDeclarationModificationService
*/
fun invalidateElement(element: KtElement) {
val container = getContainerKtElement(element)
structureElements.remove(container)
}
fun getStructureElementFor(element: KtElement): FileStructureElement { fun getStructureElementFor(element: KtElement): FileStructureElement {
val container = getContainerKtElement(element)
return structureElements.getOrPut(container) { createStructureElement(container) }
}
private fun getContainerKtElement(element: KtElement): KtElement {
val declaration = getStructureKtElement(element) val declaration = getStructureKtElement(element)
val container: KtElement val container: KtElement
if (declaration != null) { if (declaration != null) {
@@ -63,7 +80,7 @@ internal class FileStructure private constructor(
} }
} }
return getStructureElementForDeclaration(container) return container
} }
private fun getStructureKtElement(element: KtElement): KtDeclaration? { private fun getStructureKtElement(element: KtElement): KtDeclaration? {
@@ -89,31 +106,6 @@ internal class FileStructure private constructor(
return false return false
} }
private fun getStructureElementForDeclaration(declaration: KtElement): FileStructureElement {
val elementFromCache = structureElements[declaration]
if (elementFromCache == null) {
val newElement = createStructureElement(declaration)
return structureElements.putIfAbsent(declaration, newElement) ?: newElement
}
if (elementFromCache !is ReanalyzableStructureElement<*, *> || elementFromCache.isUpToDate()) {
return elementFromCache
}
val reanalyzedElement = elementFromCache.reanalyze()
return structureElements.merge(declaration, reanalyzedElement) { _, oldElement ->
if (oldElement === elementFromCache) {
reanalyzedElement
} else {
// Another thread already reanalyzed the declaration
oldElement
}
} ?: errorWithFirSpecificEntries(
"${reanalyzedElement::class.simpleName} for ${declaration::class.simpleName} is gone",
psi = declaration,
)
}
fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic> { fun getAllDiagnosticsForFile(diagnosticCheckerFilter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic> {
// TODO, KT-60799: Add a new FileStructure for file diagnostics // TODO, KT-60799: Add a new FileStructure for file diagnostics
firFile.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) firFile.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
@@ -144,9 +136,7 @@ internal class FileStructure private constructor(
override fun visitDeclaration(dcl: KtDeclaration) { override fun visitDeclaration(dcl: KtDeclaration) {
val structureElement = getStructureElementFor(dcl) val structureElement = getStructureElementFor(dcl)
structureElements += structureElement structureElements += structureElement
if (structureElement !is ReanalyzableStructureElement<*, *>) { dcl.acceptChildren(this)
dcl.acceptChildren(this)
}
} }
override fun visitModifierList(list: KtModifierList) { override fun visitModifierList(list: KtModifierList) {
@@ -175,20 +165,19 @@ internal class FileStructure private constructor(
return FileElementFactory.createFileStructureElement( return FileElementFactory.createFileStructureElement(
firDeclaration = firDeclaration, firDeclaration = firDeclaration,
ktDeclaration = declaration,
firFile = firFile, firFile = firFile,
moduleComponents = moduleComponents moduleComponents = moduleComponents
) )
} }
private fun createDanglingModifierListStructure(container: KtElement): FileStructureElement { private fun createDanglingModifierListStructure(container: KtModifierList): FileStructureElement {
val firDanglingModifierList = container.findSourceByTraversingWholeTree( val firDanglingModifierList = container.findSourceByTraversingWholeTree(
moduleComponents.firFileBuilder, moduleComponents.firFileBuilder,
firFile, firFile,
) as? FirDanglingModifierList ?: errorWithFirSpecificEntries("No dangling modifier found", psi = container) ) as? FirDanglingModifierList ?: errorWithFirSpecificEntries("No dangling modifier found", psi = container)
firDanglingModifierList.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) firDanglingModifierList.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
return DanglingTopLevelModifierListStructureElement(firFile, firDanglingModifierList, moduleComponents, container.containingKtFile) return DeclarationStructureElement(firFile, firDanglingModifierList, moduleComponents)
} }
private fun createStructureElement(container: KtElement): FileStructureElement = when { private fun createStructureElement(container: KtElement): FileStructureElement = when {
@@ -196,7 +185,7 @@ internal class FileStructure private constructor(
val firCodeFragment = firFile.codeFragment val firCodeFragment = firFile.codeFragment
firCodeFragment.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) firCodeFragment.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
ReanalyzableCodeFragmentStructureElement(firFile, container, firCodeFragment.symbol, moduleComponents) DeclarationStructureElement(firFile, firCodeFragment, moduleComponents)
} }
container is KtFile -> { container is KtFile -> {
val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile)
@@ -210,7 +199,7 @@ internal class FileStructure private constructor(
) )
} }
RootStructureElement(firFile, container, moduleComponents) RootStructureElement(firFile, moduleComponents)
} }
container is KtDeclaration -> createDeclarationStructure(container) container is KtDeclaration -> createDeclarationStructure(container)
container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container) container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container)
@@ -18,4 +18,6 @@ internal class FileStructureCache(private val moduleResolveComponents: LLFirModu
fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) { fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) {
FileStructure.build(ktFile, moduleResolveComponents) FileStructure.build(ktFile, moduleResolveComponents)
} }
fun getCachedFileStructure(ktFile: KtFile): FileStructure? = cache[ktFile]
} }
@@ -19,16 +19,10 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.correspondingProperty import org.jetbrains.kotlin.fir.correspondingProperty
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCodeFragmentSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
internal sealed class FileStructureElement(val firFile: FirFile, protected val moduleComponents: LLFirModuleResolveComponents) { internal sealed class FileStructureElement {
abstract val psi: KtAnnotated
abstract val mappings: KtToFirMapping abstract val mappings: KtToFirMapping
abstract val diagnostics: FileStructureElementDiagnostics abstract val diagnostics: FileStructureElementDiagnostics
@@ -38,8 +32,8 @@ internal sealed class FileStructureElement(val firFile: FirFile, protected val m
fun recorderFor(fir: FirElement): FirElementsRecorder = when (fir) { fun recorderFor(fir: FirElement): FirElementsRecorder = when (fir) {
is FirFile -> RootStructureElement.Recorder is FirFile -> RootStructureElement.Recorder
is FirScript -> RootScriptStructureElement.Recorder is FirScript -> RootScriptStructureElement.Recorder
is FirRegularClass -> NonReanalyzableClassDeclarationStructureElement.Recorder(fir) is FirRegularClass -> ClassDeclarationStructureElement.Recorder(fir)
else -> NonReanalyzableNonClassDeclarationStructureElement.Recorder else -> DeclarationStructureElement.Recorder
} }
} }
} }
@@ -120,101 +114,18 @@ internal class KtToFirMapping(firElement: FirElement) {
} }
} }
internal sealed class ReanalyzableStructureElement<KT : KtAnnotated, S : FirBasedSymbol<*>>( internal sealed class DeclarationBaseStructureElement<F : FirDeclaration>(val declaration: F) : FileStructureElement() {
firFile: FirFile, override val mappings: KtToFirMapping = KtToFirMapping(declaration)
val firSymbol: S,
moduleComponents: LLFirModuleResolveComponents,
) : FileStructureElement(firFile, moduleComponents) {
abstract override val psi: KtAnnotated
abstract val timestamp: Long
override val mappings = KtToFirMapping(firSymbol.fir)
/**
* Recreate [mappings] and [diagnostics]
*/
abstract fun reanalyze(): ReanalyzableStructureElement<KT, S>
fun isUpToDate(): Boolean = psi.getModificationStamp() == timestamp
override val diagnostics = FileStructureElementDiagnostics(
firFile,
SingleNonLocalDeclarationDiagnosticRetriever(firSymbol.fir),
moduleComponents,
)
}
internal class ReanalyzableCodeFragmentStructureElement(
firFile: FirFile,
override val psi: KtCodeFragment,
firSymbol: FirCodeFragmentSymbol,
moduleComponents: LLFirModuleResolveComponents,
) : ReanalyzableStructureElement<KtCodeFragment, FirCodeFragmentSymbol>(firFile, firSymbol, moduleComponents) {
override val timestamp = psi.modificationStamp
override fun reanalyze(): ReanalyzableStructureElement<KtCodeFragment, FirCodeFragmentSymbol> {
firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
return ReanalyzableCodeFragmentStructureElement(firFile, psi, firSymbol, moduleComponents)
}
}
internal class ReanalyzableFunctionStructureElement(
firFile: FirFile,
override val psi: KtNamedFunction,
firSymbol: FirFunctionSymbol<*>,
override val timestamp: Long,
moduleComponents: LLFirModuleResolveComponents,
) : ReanalyzableStructureElement<KtNamedFunction, FirFunctionSymbol<*>>(firFile, firSymbol, moduleComponents) {
override fun reanalyze(): ReanalyzableFunctionStructureElement {
firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
return ReanalyzableFunctionStructureElement(
firFile,
psi,
firSymbol,
psi.modificationStamp,
moduleComponents,
)
}
}
internal class ReanalyzablePropertyStructureElement(
firFile: FirFile,
override val psi: KtProperty,
firSymbol: FirPropertySymbol,
override val timestamp: Long,
moduleComponents: LLFirModuleResolveComponents,
) : ReanalyzableStructureElement<KtProperty, FirPropertySymbol>(firFile, firSymbol, moduleComponents) {
override fun reanalyze(): ReanalyzablePropertyStructureElement {
firSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
return ReanalyzablePropertyStructureElement(
firFile,
psi,
firSymbol,
psi.modificationStamp,
moduleComponents,
)
}
}
internal sealed class NonReanalyzableDeclarationStructureElement<T : FirDeclaration>(
val firDeclaration: T,
firFile: FirFile,
moduleComponents: LLFirModuleResolveComponents,
) : FileStructureElement(firFile, moduleComponents) {
override val mappings: KtToFirMapping = KtToFirMapping(firDeclaration)
} }
internal class RootScriptStructureElement( internal class RootScriptStructureElement(
firFile: FirFile, file: FirFile,
script: FirScript, script: FirScript,
override val psi: KtScript,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
) : NonReanalyzableDeclarationStructureElement<FirScript>(script, firFile, moduleComponents) { ) : DeclarationBaseStructureElement<FirScript>(script) {
override val diagnostics: FileStructureElementDiagnostics = FileStructureElementDiagnostics( override val diagnostics: FileStructureElementDiagnostics = FileStructureElementDiagnostics(
firFile, file,
ScriptDiagnosticRetriever(firDeclaration), ScriptDiagnosticRetriever(declaration),
moduleComponents, moduleComponents,
) )
@@ -236,15 +147,14 @@ internal fun <T, R> visitScriptDependentElements(script: FirScript, visitor: Fir
} }
} }
internal class NonReanalyzableClassDeclarationStructureElement( internal class ClassDeclarationStructureElement(
firFile: FirFile, file: FirFile,
fir: FirRegularClass, clazz: FirRegularClass,
override val psi: KtClassOrObject,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
) : NonReanalyzableDeclarationStructureElement<FirRegularClass>(fir, firFile, moduleComponents) { ) : DeclarationBaseStructureElement<FirRegularClass>(clazz) {
override val diagnostics = FileStructureElementDiagnostics( override val diagnostics = FileStructureElementDiagnostics(
firFile, file,
ClassDiagnosticRetriever(firDeclaration), ClassDiagnosticRetriever(declaration),
moduleComponents, moduleComponents,
) )
@@ -263,7 +173,7 @@ internal class NonReanalyzableClassDeclarationStructureElement(
(constructor is FirPrimaryConstructor || constructor is FirErrorPrimaryConstructor) && (constructor is FirPrimaryConstructor || constructor is FirErrorPrimaryConstructor) &&
constructor.source?.kind == KtFakeSourceElementKind.ImplicitConstructor constructor.source?.kind == KtFakeSourceElementKind.ImplicitConstructor
) { ) {
NonReanalyzableNonClassDeclarationStructureElement.Recorder.visitConstructor(constructor, data) DeclarationStructureElement.Recorder.visitConstructor(constructor, data)
} }
} }
@@ -283,15 +193,14 @@ internal class NonReanalyzableClassDeclarationStructureElement(
} }
} }
internal class NonReanalyzableNonClassDeclarationStructureElement( internal class DeclarationStructureElement(
firFile: FirFile, file: FirFile,
fir: FirDeclaration, declaration: FirDeclaration,
override val psi: KtDeclaration,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
) : NonReanalyzableDeclarationStructureElement<FirDeclaration>(fir, firFile, moduleComponents) { ) : DeclarationBaseStructureElement<FirDeclaration>(declaration) {
override val diagnostics = FileStructureElementDiagnostics( override val diagnostics = FileStructureElementDiagnostics(
firFile, file,
SingleNonLocalDeclarationDiagnosticRetriever(firDeclaration), SingleNonLocalDeclarationDiagnosticRetriever(declaration),
moduleComponents, moduleComponents,
) )
@@ -310,26 +219,12 @@ internal class NonReanalyzableNonClassDeclarationStructureElement(
} }
} }
internal class DanglingTopLevelModifierListStructureElement(
firFile: FirFile,
fir: FirDanglingModifierList,
moduleComponents: LLFirModuleResolveComponents,
override val psi: KtAnnotated,
) : NonReanalyzableDeclarationStructureElement<FirDanglingModifierList>(fir, firFile, moduleComponents) {
override val diagnostics = FileStructureElementDiagnostics(
firFile,
SingleNonLocalDeclarationDiagnosticRetriever(firDeclaration),
moduleComponents,
)
}
internal class RootStructureElement( internal class RootStructureElement(
firFile: FirFile, val file: FirFile,
override val psi: KtFile,
moduleComponents: LLFirModuleResolveComponents, moduleComponents: LLFirModuleResolveComponents,
) : FileStructureElement(firFile, moduleComponents) { ) : FileStructureElement() {
override val mappings = KtToFirMapping(firFile) override val mappings = KtToFirMapping(file)
override val diagnostics = FileStructureElementDiagnostics(firFile, FileDiagnosticRetriever, moduleComponents) override val diagnostics = FileStructureElementDiagnostics(file, FileDiagnosticRetriever, moduleComponents)
object Recorder : FirElementsRecorder() { object Recorder : FirElementsRecorder() {
override fun visitElement(element: FirElement, data: MutableMap<KtElement, FirElement>) { override fun visitElement(element: FirElement, data: MutableMap<KtElement, FirElement>) {
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.LLFirDeclarationModificationService.ModificationType import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.LLFirDeclarationModificationService.ModificationType
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
@@ -24,6 +26,7 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.KtAnnotated import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
/** /**
* This service is responsible for processing incoming [PsiElement] changes to reflect them on FIR tree. * This service is responsible for processing incoming [PsiElement] changes to reflect them on FIR tree.
@@ -67,7 +70,7 @@ class LLFirDeclarationModificationService(val project: Project) {
} }
} }
private fun inBlockModification(declaration: PsiElement) { private fun inBlockModification(declaration: KtElement) {
val ktModule = ProjectStructureProvider.getModule(project, declaration, contextualModule = null) val ktModule = ProjectStructureProvider.getModule(project, declaration, contextualModule = null)
val resolveSession = ktModule.getFirResolveSession(project) val resolveSession = ktModule.getFirResolveSession(project)
val firDeclaration = when (declaration) { val firDeclaration = when (declaration) {
@@ -80,6 +83,21 @@ class LLFirDeclarationModificationService(val project: Project) {
} }
invalidateAfterInBlockModification(firDeclaration) invalidateAfterInBlockModification(firDeclaration)
val moduleSession = firDeclaration.llFirResolvableSession ?: errorWithFirSpecificEntries(
"${LLFirResolvableModuleSession::class.simpleName} is not found",
fir = firDeclaration,
psi = declaration,
) {
withEntry("session", resolveSession) { it.toString() }
}
val fileStructure = moduleSession.moduleComponents
.fileStructureCache
.getCachedFileStructure(declaration.containingKtFile)
?: return // we do not have a cache for this file
fileStructure.invalidateElement(declaration)
} }
private fun outOfBlockModification(element: PsiElement) { private fun outOfBlockModification(element: PsiElement) {
@@ -1,4 +1,4 @@
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
val x = object: Any() { val x = object: Any() {
fun foo(){} fun foo(){}
} }
@@ -1,7 +1,7 @@
open class B(x: () -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ open class B(x: () -> Unit)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
class A()/* NonReanalyzableNonClassDeclarationStructureElement */ : B(1, { class A()/* DeclarationStructureElement */ : B(1, {
foo() foo()
})/* NonReanalyzableClassDeclarationStructureElement */ })/* ClassDeclarationStructureElement */
fun foo() {/* ReanalyzableFunctionStructureElement */} fun foo() {/* DeclarationStructureElement */}
@@ -1,7 +1,7 @@
open class B(x: () -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ open class B(x: () -> Unit)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
class A : B(1, { class A : B(1, {
foo() foo()
})/* NonReanalyzableClassDeclarationStructureElement */ })/* ClassDeclarationStructureElement */
fun foo() {/* ReanalyzableFunctionStructureElement */} fun foo() {/* DeclarationStructureElement */}
@@ -1,17 +1,17 @@
open class A(x: () -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ open class A(x: () -> Unit)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
class B : A {/* NonReanalyzableClassDeclarationStructureElement */ class B : A {/* ClassDeclarationStructureElement */
constructor(i: Int) : super( constructor(i: Int) : super(
{ {
foo(i) foo(i)
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
constructor(l: Long) : super( constructor(l: Long) : super(
{ {
foo(l) foo(l)
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
fun foo(any: Any) {/* ReanalyzableFunctionStructureElement */} fun foo(any: Any) {/* DeclarationStructureElement */}
@@ -1,11 +1,11 @@
open class A(x: () -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ open class A(x: () -> Unit)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
class B : A {/* NonReanalyzableClassDeclarationStructureElement */ class B : A {/* ClassDeclarationStructureElement */
constructor(i: Int) : super( constructor(i: Int) : super(
{ {
foo(i) foo(i)
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
fun foo(any: Any) {/* ReanalyzableFunctionStructureElement */} fun foo(any: Any) {/* DeclarationStructureElement */}
+3 -3
View File
@@ -1,6 +1,6 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
} }
fun y(): Int = 10/* ReanalyzableFunctionStructureElement */ fun y(): Int = 10/* DeclarationStructureElement */
} }
@@ -1,8 +1,8 @@
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
fun q(): C {/* ReanalyzableFunctionStructureElement */} fun q(): C {/* DeclarationStructureElement */}
private val y = q()/* NonReanalyzableNonClassDeclarationStructureElement */ private val y = q()/* DeclarationStructureElement */
fun foo(a: A) = with(a) { fun foo(a: A) = with(a) {
bar("a", y) bar("a", y)
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
} }
@@ -1,11 +1,11 @@
class X {/* NonReanalyzableClassDeclarationStructureElement */ class X {/* ClassDeclarationStructureElement */
var x: Int/* ReanalyzablePropertyStructureElement */ var x: Int/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
val y = 42/* NonReanalyzableNonClassDeclarationStructureElement */ val y = 42/* DeclarationStructureElement */
var z: Int = 15/* NonReanalyzableNonClassDeclarationStructureElement */ var z: Int = 15/* DeclarationStructureElement */
} }
@@ -1,11 +1,11 @@
/* RootScriptStructureElement */class X {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class X {/* ClassDeclarationStructureElement */
var x: Int/* ReanalyzablePropertyStructureElement */ var x: Int/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
val y = 42/* NonReanalyzableNonClassDeclarationStructureElement */ val y = 42/* DeclarationStructureElement */
var z: Int = 15/* NonReanalyzableNonClassDeclarationStructureElement */ var z: Int = 15/* DeclarationStructureElement */
} }
@@ -1,6 +1,6 @@
/* RootScriptStructureElement */class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class A {/* ClassDeclarationStructureElement */
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
} }
fun y(): Int = 10/* ReanalyzableFunctionStructureElement */ fun y(): Int = 10/* DeclarationStructureElement */
} }
@@ -1 +1 @@
class A(var x: Int)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ class A(var x: Int)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
@@ -1 +1 @@
class A(val x: String)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ class A(val x: String)/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
@@ -5,6 +5,6 @@ class A(
@field:Ann @field:Ann
@property:Ann @property:Ann
var x: Int var x: Int
)/* NonReanalyzableNonClassDeclarationStructureElement *//* NonReanalyzableClassDeclarationStructureElement */ )/* DeclarationStructureElement *//* ClassDeclarationStructureElement */
annotation class Ann/* NonReanalyzableClassDeclarationStructureElement */ annotation class Ann/* ClassDeclarationStructureElement */
@@ -1,9 +1,9 @@
class A class A
(val a: Int)/* NonReanalyzableNonClassDeclarationStructureElement */ (val a: Int)/* DeclarationStructureElement */
{/* NonReanalyzableClassDeclarationStructureElement */ {/* ClassDeclarationStructureElement */
constructor() : this(1) {/* NonReanalyzableNonClassDeclarationStructureElement */ constructor() : this(1) {/* DeclarationStructureElement */
} }
} }
@@ -1,9 +1,9 @@
/* RootScriptStructureElement */class A /* RootScriptStructureElement */class A
(val a: Int)/* NonReanalyzableNonClassDeclarationStructureElement */ (val a: Int)/* DeclarationStructureElement */
{/* NonReanalyzableClassDeclarationStructureElement */ {/* ClassDeclarationStructureElement */
constructor() : this(1) {/* NonReanalyzableNonClassDeclarationStructureElement */ constructor() : this(1) {/* DeclarationStructureElement */
} }
} }
@@ -1,14 +1,14 @@
class Foo {/* NonReanalyzableClassDeclarationStructureElement */ class Foo {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
class Bar {/* NonReanalyzableClassDeclarationStructureElement */ class Bar {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
class Outer {/* NonReanalyzableClassDeclarationStructureElement */ class Outer {/* ClassDeclarationStructureElement */
class Inner {/* NonReanalyzableClassDeclarationStructureElement */ class Inner {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
class Local { class Local {
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
@@ -1,14 +1,14 @@
/* RootScriptStructureElement */class Foo {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class Foo {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
class Bar {/* NonReanalyzableClassDeclarationStructureElement */ class Bar {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
class Outer {/* NonReanalyzableClassDeclarationStructureElement */ class Outer {/* ClassDeclarationStructureElement */
class Inner {/* NonReanalyzableClassDeclarationStructureElement */ class Inner {/* ClassDeclarationStructureElement */
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
class Local { class Local {
@Suppress("") @MustBeDocumented @Suppress("") @MustBeDocumented
} }
@@ -1 +1 @@
@Suppress("") @MustBeDocumented/* DanglingTopLevelModifierListStructureElement */ @Suppress("") @MustBeDocumented/* DeclarationStructureElement */
@@ -1,11 +1,11 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
val a = myRun { val a = myRun {
class X() class X()
val y = 10 val y = 10
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
} }
inline fun <R> myRun(block: () -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <R> myRun(block: () -> R): R {/* DeclarationStructureElement */
return block() return block()
} }
@@ -1,11 +1,11 @@
/* RootScriptStructureElement */class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class A {/* ClassDeclarationStructureElement */
val a = run { val a = run {
class X() class X()
val y = 10 val y = 10
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
} }
inline fun <R> run(block: () -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <R> run(block: () -> R): R {/* DeclarationStructureElement */
return block() return block()
} }
+2 -2
View File
@@ -1,3 +1,3 @@
enum class Enum(val x: Int)/* NonReanalyzableNonClassDeclarationStructureElement */ {/* NonReanalyzableClassDeclarationStructureElement */ enum class Enum(val x: Int)/* DeclarationStructureElement */ {/* ClassDeclarationStructureElement */
A(1),/* NonReanalyzableNonClassDeclarationStructureElement */ A(1),/* DeclarationStructureElement */
} }
@@ -1,13 +1,13 @@
enum class A {/* NonReanalyzableClassDeclarationStructureElement */ enum class A {/* ClassDeclarationStructureElement */
X,/* NonReanalyzableNonClassDeclarationStructureElement */ X,/* DeclarationStructureElement */
Y,/* NonReanalyzableNonClassDeclarationStructureElement */ Y,/* DeclarationStructureElement */
Z Z
;/* NonReanalyzableNonClassDeclarationStructureElement */ ;/* DeclarationStructureElement */
fun foo(){/* ReanalyzableFunctionStructureElement */} fun foo(){/* DeclarationStructureElement */}
val x = 10/* NonReanalyzableNonClassDeclarationStructureElement */ val x = 10/* DeclarationStructureElement */
fun bar() = 10/* NonReanalyzableNonClassDeclarationStructureElement */ fun bar() = 10/* DeclarationStructureElement */
} }
@@ -1,13 +1,13 @@
/* RootScriptStructureElement */enum class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */enum class A {/* ClassDeclarationStructureElement */
X,/* NonReanalyzableNonClassDeclarationStructureElement */ X,/* DeclarationStructureElement */
Y,/* NonReanalyzableNonClassDeclarationStructureElement */ Y,/* DeclarationStructureElement */
Z Z
;/* NonReanalyzableNonClassDeclarationStructureElement */ ;/* DeclarationStructureElement */
fun foo(){/* ReanalyzableFunctionStructureElement */} fun foo(){/* DeclarationStructureElement */}
val x = 10/* NonReanalyzableNonClassDeclarationStructureElement */ val x = 10/* DeclarationStructureElement */
fun bar() = 10/* NonReanalyzableNonClassDeclarationStructureElement */ fun bar() = 10/* DeclarationStructureElement */
} }
@@ -1,13 +1,13 @@
enum class A {/* NonReanalyzableClassDeclarationStructureElement */ enum class A {/* ClassDeclarationStructureElement */
X {/* NonReanalyzableNonClassDeclarationStructureElement */ X {/* DeclarationStructureElement */
fun localInX() = 1 fun localInX() = 1
}, },
Y {/* NonReanalyzableNonClassDeclarationStructureElement */ Y {/* DeclarationStructureElement */
override fun foo() {} override fun foo() {}
}, },
Z, Z,
;/* NonReanalyzableNonClassDeclarationStructureElement */ ;/* DeclarationStructureElement */
open fun foo() {/* ReanalyzableFunctionStructureElement */} open fun foo() {/* DeclarationStructureElement */}
} }
@@ -1,13 +1,13 @@
/* RootScriptStructureElement */enum class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */enum class A {/* ClassDeclarationStructureElement */
X {/* NonReanalyzableNonClassDeclarationStructureElement */ X {/* DeclarationStructureElement */
fun localInX() = 1 fun localInX() = 1
}, },
Y {/* NonReanalyzableNonClassDeclarationStructureElement */ Y {/* DeclarationStructureElement */
override fun foo() {} override fun foo() {}
}, },
Z, Z,
;/* NonReanalyzableNonClassDeclarationStructureElement */ ;/* DeclarationStructureElement */
open fun foo() {/* ReanalyzableFunctionStructureElement */} open fun foo() {/* DeclarationStructureElement */}
} }
@@ -1,3 +1,3 @@
fun main() {/* ReanalyzableFunctionStructureElement */ fun main() {/* DeclarationStructureElement */
} }
@@ -1,9 +1,9 @@
fun bar(a: Int, b: (Boolean) -> Unit) {/* ReanalyzableFunctionStructureElement */ fun bar(a: Int, b: (Boolean) -> Unit) {/* DeclarationStructureElement */
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun foo(x: String, y: () -> String) {/* ReanalyzableFunctionStructureElement */ fun foo(x: String, y: () -> String) {/* DeclarationStructureElement */
} }
} }
@@ -1,5 +1,5 @@
import java.util.Collections import java.util.Collections
fun <T> checkSubtype(t: T) = t/* NonReanalyzableNonClassDeclarationStructureElement */ fun <T> checkSubtype(t: T) = t/* DeclarationStructureElement */
val ab = checkSubtype<List<Int>?>(Collections.emptyList<Int>())/* NonReanalyzableNonClassDeclarationStructureElement */ val ab = checkSubtype<List<Int>?>(Collections.emptyList<Int>())/* DeclarationStructureElement */
@@ -1,3 +1,3 @@
class A(val x: Int = 10, val b: String)/* NonReanalyzableNonClassDeclarationStructureElement */ {/* NonReanalyzableClassDeclarationStructureElement */ class A(val x: Int = 10, val b: String)/* DeclarationStructureElement */ {/* ClassDeclarationStructureElement */
} }
@@ -1,5 +1,5 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
init {/* NonReanalyzableNonClassDeclarationStructureElement */ init {/* DeclarationStructureElement */
val x = 10 val x = 10
class B class B
} }
@@ -1,5 +1,5 @@
/* RootScriptStructureElement */class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class A {/* ClassDeclarationStructureElement */
init {/* NonReanalyzableNonClassDeclarationStructureElement */ init {/* DeclarationStructureElement */
val x = 10 val x = 10
class B class B
} }
@@ -2,12 +2,12 @@ val x = myRun {
val inLambda = 10 val inLambda = 10
println(inLambda) println(inLambda)
inLambda inLambda
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
fun println(any: Any) {/* ReanalyzableFunctionStructureElement */ fun println(any: Any) {/* DeclarationStructureElement */
} }
inline fun <R> myRun(block: () -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <R> myRun(block: () -> R): R {/* DeclarationStructureElement */
return block() return block()
} }
@@ -1,13 +1,13 @@
inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* DeclarationStructureElement */
return receiver.block() return receiver.block()
} }
inline fun <T, R> T.let(block: (T) -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> T.let(block: (T) -> R): R {/* DeclarationStructureElement */
return block(this) return block(this)
} }
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
fun foo(a: Int) = with(a) { fun foo(a: Int) = with(a) {
toString().let { it } toString().let { it }
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
} }
@@ -1,14 +1,14 @@
inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* DeclarationStructureElement */
return receiver.block() return receiver.block()
} }
inline fun <T, R> T.let(block: (T) -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> T.let(block: (T) -> R): R {/* DeclarationStructureElement */
return block(this) return block(this)
} }
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
val a: Int = 10/* NonReanalyzableNonClassDeclarationStructureElement */ val a: Int = 10/* DeclarationStructureElement */
val x = with(a) { val x = with(a) {
toString().let { it } toString().let { it }
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
} }
@@ -1,13 +1,13 @@
inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> with(receiver: T, block: T.() -> R): R {/* DeclarationStructureElement */
return receiver.block() return receiver.block()
} }
inline fun <T, R> T.let(block: (T) -> R): R {/* ReanalyzableFunctionStructureElement */ inline fun <T, R> T.let(block: (T) -> R): R {/* DeclarationStructureElement */
return block(this) return block(this)
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
val a = with(1) { val a = with(1) {
this.let { it } this.let { it }
}.let { 2 } }.let { 2 }
@@ -1,9 +1,9 @@
fun a() {/* ReanalyzableFunctionStructureElement */ fun a() {/* DeclarationStructureElement */
class X class X
} }
class Y {/* NonReanalyzableClassDeclarationStructureElement */ class Y {/* ClassDeclarationStructureElement */
fun b() {/* ReanalyzableFunctionStructureElement */ fun b() {/* DeclarationStructureElement */
class Z class Z
} }
} }
@@ -1,4 +1,4 @@
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
class Local { class Local {
fun foo(){} fun foo(){}
} }
@@ -1,9 +1,9 @@
/* RootScriptStructureElement */fun a() {/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun a() {/* DeclarationStructureElement */
class X class X
} }
class Y {/* NonReanalyzableClassDeclarationStructureElement */ class Y {/* ClassDeclarationStructureElement */
fun b() {/* ReanalyzableFunctionStructureElement */ fun b() {/* DeclarationStructureElement */
class Z class Z
} }
} }
@@ -1,5 +1,5 @@
class Outer {/* NonReanalyzableClassDeclarationStructureElement */ class Outer {/* ClassDeclarationStructureElement */
val i: Int = 1/* ReanalyzablePropertyStructureElement */ val i: Int = 1/* DeclarationStructureElement */
get() { get() {
class Inner { class Inner {
var i: Int = 2 var i: Int = 2
@@ -20,7 +20,7 @@ class Outer {/* NonReanalyzableClassDeclarationStructureElement */
return field return field
} }
val j: Int = 4/* ReanalyzablePropertyStructureElement */ val j: Int = 4/* DeclarationStructureElement */
get() { get() {
fun local() { fun local() {
field++ field++
@@ -1,11 +1,11 @@
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
fun y() { fun y() {
} }
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun z() {/* ReanalyzableFunctionStructureElement */ fun z() {/* DeclarationStructureElement */
fun q() { fun q() {
} }
@@ -1,11 +1,11 @@
/* RootScriptStructureElement */fun x() {/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun x() {/* DeclarationStructureElement */
fun y() { fun y() {
} }
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun z() {/* ReanalyzableFunctionStructureElement */ fun z() {/* DeclarationStructureElement */
fun q() { fun q() {
} }
@@ -1,3 +1,3 @@
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
fun local() = 0 fun local() = 0
} }
@@ -1,14 +1,14 @@
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
var x: Int var x: Int
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun q() {/* ReanalyzableFunctionStructureElement */ fun q() {/* DeclarationStructureElement */
val y = 42 val y = 42
} }
} }
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
class C {/* NonReanalyzableClassDeclarationStructureElement */ class C {/* ClassDeclarationStructureElement */
fun u() {/* ReanalyzableFunctionStructureElement */ fun u() {/* DeclarationStructureElement */
var z: Int = 15 var z: Int = 15
} }
} }
@@ -1,14 +1,14 @@
/* RootScriptStructureElement */fun foo() {/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun foo() {/* DeclarationStructureElement */
var x: Int var x: Int
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun q() {/* ReanalyzableFunctionStructureElement */ fun q() {/* DeclarationStructureElement */
val y = 42 val y = 42
} }
} }
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
class C {/* NonReanalyzableClassDeclarationStructureElement */ class C {/* ClassDeclarationStructureElement */
fun u() {/* ReanalyzableFunctionStructureElement */ fun u() {/* DeclarationStructureElement */
var z: Int = 15 var z: Int = 15
} }
} }
@@ -1,4 +1,4 @@
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
fun local() { fun local() {
println("local") println("local")
} }
@@ -1,7 +1,7 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun foo1() = 10/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo1() = 10/* DeclarationStructureElement */
fun foo2() {/* ReanalyzableFunctionStructureElement */ fun foo2() {/* DeclarationStructureElement */
} }
} }
@@ -1,7 +1,7 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun foo1() = 10/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo1() = 10/* DeclarationStructureElement */
fun foo2() {/* ReanalyzableFunctionStructureElement */ fun foo2() {/* DeclarationStructureElement */
} }
} }
@@ -1,3 +1,3 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
typealias X = Int/* NonReanalyzableNonClassDeclarationStructureElement */ typealias X = Int/* DeclarationStructureElement */
} }
@@ -1,3 +1,3 @@
/* RootScriptStructureElement */class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class A {/* ClassDeclarationStructureElement */
typealias X = Int/* NonReanalyzableNonClassDeclarationStructureElement */ typealias X = Int/* DeclarationStructureElement */
} }
@@ -1,15 +1,15 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
} }
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
} }
class C {/* NonReanalyzableClassDeclarationStructureElement */ class C {/* ClassDeclarationStructureElement */
} }
class D {/* NonReanalyzableClassDeclarationStructureElement */ class D {/* ClassDeclarationStructureElement */
} }
@@ -1,7 +1,7 @@
fun foo1() = 1/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo1() = 1/* DeclarationStructureElement */
fun foo2() = 2/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo2() = 2/* DeclarationStructureElement */
fun foo3() = 3/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo3() = 3/* DeclarationStructureElement */
fun foo4() = 4/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo4() = 4/* DeclarationStructureElement */
@@ -1,15 +1,15 @@
fun foo1() {/* ReanalyzableFunctionStructureElement */ fun foo1() {/* DeclarationStructureElement */
println("foo1") println("foo1")
} }
fun foo2() {/* ReanalyzableFunctionStructureElement */ fun foo2() {/* DeclarationStructureElement */
println("foo2") println("foo2")
} }
fun foo3() {/* ReanalyzableFunctionStructureElement */ fun foo3() {/* DeclarationStructureElement */
println("foo3") println("foo3")
} }
fun foo4() {/* ReanalyzableFunctionStructureElement */ fun foo4() {/* DeclarationStructureElement */
println("foo4") println("foo4")
} }
@@ -1,10 +1,10 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
} }
object C {/* NonReanalyzableClassDeclarationStructureElement */ object C {/* ClassDeclarationStructureElement */
class D {/* NonReanalyzableClassDeclarationStructureElement */ class D {/* ClassDeclarationStructureElement */
} }
} }
@@ -1,7 +1,7 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun y() {/* ReanalyzableFunctionStructureElement */} fun y() {/* DeclarationStructureElement */}
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
fun x() {/* ReanalyzableFunctionStructureElement */} fun x() {/* DeclarationStructureElement */}
} }
} }
@@ -1,16 +1,16 @@
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
} }
class C {/* NonReanalyzableClassDeclarationStructureElement */ class C {/* ClassDeclarationStructureElement */
} }
} }
class E {/* NonReanalyzableClassDeclarationStructureElement */ class E {/* ClassDeclarationStructureElement */
} }
fun y(): Int = 10/* ReanalyzableFunctionStructureElement */ fun y(): Int = 10/* DeclarationStructureElement */
} }
@@ -1,16 +1,16 @@
/* RootScriptStructureElement */class A {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class A {/* ClassDeclarationStructureElement */
class B {/* NonReanalyzableClassDeclarationStructureElement */ class B {/* ClassDeclarationStructureElement */
fun x() {/* ReanalyzableFunctionStructureElement */ fun x() {/* DeclarationStructureElement */
} }
class C {/* NonReanalyzableClassDeclarationStructureElement */ class C {/* ClassDeclarationStructureElement */
} }
} }
class E {/* NonReanalyzableClassDeclarationStructureElement */ class E {/* ClassDeclarationStructureElement */
} }
fun y(): Int = 10/* ReanalyzableFunctionStructureElement */ fun y(): Int = 10/* DeclarationStructureElement */
} }
@@ -1,11 +1,11 @@
var x: Int = 10/* ReanalyzablePropertyStructureElement */ var x: Int = 10/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
class X {/* NonReanalyzableClassDeclarationStructureElement */ class X {/* ClassDeclarationStructureElement */
var y: Int = 10/* ReanalyzablePropertyStructureElement */ var y: Int = 10/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
@@ -1,11 +1,11 @@
/* RootScriptStructureElement */var x: Int = 10/* ReanalyzablePropertyStructureElement */ /* RootScriptStructureElement */var x: Int = 10/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
class X {/* NonReanalyzableClassDeclarationStructureElement */ class X {/* ClassDeclarationStructureElement */
var y: Int = 10/* ReanalyzablePropertyStructureElement */ var y: Int = 10/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
@@ -1,4 +1,4 @@
var withGetterAndSetter: Int = 42/* ReanalyzablePropertyStructureElement */ var withGetterAndSetter: Int = 42/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
@@ -1,14 +1,14 @@
abstract class Foo {/* NonReanalyzableClassDeclarationStructureElement */ abstract class Foo {/* ClassDeclarationStructureElement */
abstract var id: Int/* ReanalyzablePropertyStructureElement */ abstract var id: Int/* DeclarationStructureElement */
protected set protected set
} }
class Bar : Foo() {/* NonReanalyzableClassDeclarationStructureElement */ class Bar : Foo() {/* ClassDeclarationStructureElement */
override var id: Int = 1/* ReanalyzablePropertyStructureElement */ override var id: Int = 1/* DeclarationStructureElement */
public set public set
} }
fun test() {/* ReanalyzableFunctionStructureElement */ fun test() {/* DeclarationStructureElement */
val bar = Bar() val bar = Bar()
bar.id = 1 bar.id = 1
} }
@@ -1,51 +1,51 @@
open class A(init: A.() -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement */ {/* NonReanalyzableClassDeclarationStructureElement */ open class A(init: A.() -> Unit)/* DeclarationStructureElement */ {/* ClassDeclarationStructureElement */
val prop: String = ""/* NonReanalyzableNonClassDeclarationStructureElement */ val prop: String = ""/* DeclarationStructureElement */
} }
object B : A({})/* NonReanalyzableClassDeclarationStructureElement */ object B : A({})/* ClassDeclarationStructureElement */
object C : A( object C : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
)/* NonReanalyzableClassDeclarationStructureElement */ )/* ClassDeclarationStructureElement */
class D : A( class D : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
)/* NonReanalyzableClassDeclarationStructureElement */ )/* ClassDeclarationStructureElement */
class E()/* NonReanalyzableNonClassDeclarationStructureElement */ : A( class E()/* DeclarationStructureElement */ : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
)/* NonReanalyzableClassDeclarationStructureElement */ )/* ClassDeclarationStructureElement */
class F : A( class F : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
constructor()/* NonReanalyzableNonClassDeclarationStructureElement */ constructor()/* DeclarationStructureElement */
} }
class G : A( class G : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
constructor() : super( constructor() : super(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
class H : A {/* NonReanalyzableClassDeclarationStructureElement */ class H : A {/* ClassDeclarationStructureElement */
constructor() : super( constructor() : super(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
@@ -1,13 +1,13 @@
/* RootScriptStructureElement */class Builder {/* NonReanalyzableClassDeclarationStructureElement */ /* RootScriptStructureElement */class Builder {/* ClassDeclarationStructureElement */
var version: String = ""/* NonReanalyzableNonClassDeclarationStructureElement */ var version: String = ""/* DeclarationStructureElement */
fun execute() {/* ReanalyzableFunctionStructureElement */ fun execute() {/* DeclarationStructureElement */
println(version) println(version)
} }
} }
fun build(action: Builder.() -> Unit) = Builder().apply(action)/* NonReanalyzableNonClassDeclarationStructureElement */ fun build(action: Builder.() -> Unit) = Builder().apply(action)/* DeclarationStructureElement */
fun build2(action: Builder.() -> Unit): Builder = Builder().apply(action)/* ReanalyzableFunctionStructureElement */ fun build2(action: Builder.() -> Unit): Builder = Builder().apply(action)/* DeclarationStructureElement */
build { build {
version = "123" version = "123"
@@ -22,6 +22,6 @@ build {
val builder = build { val builder = build {
version = "321" version = "321"
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
builder.execute() builder.execute()
@@ -1,3 +1,3 @@
class A(val x: Int = 10, val b: String)/* NonReanalyzableNonClassDeclarationStructureElement */ {/* NonReanalyzableClassDeclarationStructureElement */ class A(val x: Int = 10, val b: String)/* DeclarationStructureElement */ {/* ClassDeclarationStructureElement */
constructor(i: Int) : this(x = 1, b = i.toString())/* NonReanalyzableNonClassDeclarationStructureElement */ constructor(i: Int) : this(x = 1, b = i.toString())/* DeclarationStructureElement */
} }
@@ -1,6 +1,6 @@
@Target(AnnotationTarget.TYPE) @Target(AnnotationTarget.TYPE)
annotation class Anno/* NonReanalyzableClassDeclarationStructureElement */ annotation class Anno/* ClassDeclarationStructureElement */
open class A/* NonReanalyzableClassDeclarationStructureElement */ open class A/* ClassDeclarationStructureElement */
class B : @Anno A()/* NonReanalyzableClassDeclarationStructureElement */ class B : @Anno A()/* ClassDeclarationStructureElement */
@@ -1,6 +1,6 @@
@Target(AnnotationTarget.TYPE) @Target(AnnotationTarget.TYPE)
annotation class Anno/* NonReanalyzableClassDeclarationStructureElement */ annotation class Anno/* ClassDeclarationStructureElement */
interface A/* NonReanalyzableClassDeclarationStructureElement */ interface A/* ClassDeclarationStructureElement */
class B : @Anno A/* NonReanalyzableClassDeclarationStructureElement */ class B : @Anno A/* ClassDeclarationStructureElement */
@@ -1,16 +1,16 @@
open class A open class A
(init: A.() -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement */ (init: A.() -> Unit)/* DeclarationStructureElement */
{/* NonReanalyzableClassDeclarationStructureElement */ {/* ClassDeclarationStructureElement */
val prop: String = ""/* NonReanalyzableNonClassDeclarationStructureElement */ val prop: String = ""/* DeclarationStructureElement */
} }
class B()/* NonReanalyzableNonClassDeclarationStructureElement */ : A()/* NonReanalyzableClassDeclarationStructureElement */ class B()/* DeclarationStructureElement */ : A()/* ClassDeclarationStructureElement */
object C : A( object C : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
} }
@@ -20,16 +20,16 @@ val f = object : A(
} }
) { ) {
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
class D : A( class D : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
constructor(): super( constructor(): super(
{ {
fun boo() = prop.toString() fun boo() = prop.toString()
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
@@ -1,16 +1,16 @@
/* RootScriptStructureElement */open class A /* RootScriptStructureElement */open class A
(init: A.() -> Unit)/* NonReanalyzableNonClassDeclarationStructureElement */ (init: A.() -> Unit)/* DeclarationStructureElement */
{/* NonReanalyzableClassDeclarationStructureElement */ {/* ClassDeclarationStructureElement */
val prop: String = ""/* NonReanalyzableNonClassDeclarationStructureElement */ val prop: String = ""/* DeclarationStructureElement */
} }
class B()/* NonReanalyzableNonClassDeclarationStructureElement */ : A()/* NonReanalyzableClassDeclarationStructureElement */ class B()/* DeclarationStructureElement */ : A()/* ClassDeclarationStructureElement */
object C : A( object C : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
} }
@@ -20,16 +20,16 @@ val f = object : A(
} }
) { ) {
}/* NonReanalyzableNonClassDeclarationStructureElement */ }/* DeclarationStructureElement */
class D : A( class D : A(
{ {
fun foo() = B.prop.toString() fun foo() = B.prop.toString()
} }
) {/* NonReanalyzableClassDeclarationStructureElement */ ) {/* ClassDeclarationStructureElement */
constructor(): super( constructor(): super(
{ {
fun boo() = prop.toString() fun boo() = prop.toString()
} }
)/* NonReanalyzableNonClassDeclarationStructureElement */ )/* DeclarationStructureElement */
} }
@@ -1,7 +1,7 @@
interface A<T>/* NonReanalyzableClassDeclarationStructureElement */ interface A<T>/* ClassDeclarationStructureElement */
typealias AS = A<String>/* NonReanalyzableNonClassDeclarationStructureElement */ typealias AS = A<String>/* DeclarationStructureElement */
class C : AS {/* NonReanalyzableClassDeclarationStructureElement */ class C : AS {/* ClassDeclarationStructureElement */
constructor()/* NonReanalyzableNonClassDeclarationStructureElement */ constructor()/* DeclarationStructureElement */
} }
@@ -1 +1 @@
fun foo(): Int = 42/* ReanalyzableFunctionStructureElement */ fun foo(): Int = 42/* DeclarationStructureElement */
@@ -1 +1 @@
/* RootScriptStructureElement */fun foo(): Int = 42/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun foo(): Int = 42/* DeclarationStructureElement */
@@ -1 +1 @@
fun foo() = 42/* NonReanalyzableNonClassDeclarationStructureElement */ fun foo() = 42/* DeclarationStructureElement */
@@ -1 +1 @@
/* RootScriptStructureElement */fun foo() = 42/* NonReanalyzableNonClassDeclarationStructureElement */ /* RootScriptStructureElement */fun foo() = 42/* DeclarationStructureElement */
@@ -1,4 +1,4 @@
fun foo(): Int {/* ReanalyzableFunctionStructureElement */ fun foo(): Int {/* DeclarationStructureElement */
println("") println("")
return 10 return 10
} }
@@ -1,4 +1,4 @@
/* RootScriptStructureElement */fun foo(): Int {/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun foo(): Int {/* DeclarationStructureElement */
println("") println("")
return 10 return 10
} }
@@ -1,9 +1,9 @@
var x: Int/* ReanalyzablePropertyStructureElement */ var x: Int/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
val y = 42/* NonReanalyzableNonClassDeclarationStructureElement */ val y = 42/* DeclarationStructureElement */
var z: Int = 15/* NonReanalyzableNonClassDeclarationStructureElement */ var z: Int = 15/* DeclarationStructureElement */
@@ -1,9 +1,9 @@
/* RootScriptStructureElement */var x: Int/* ReanalyzablePropertyStructureElement */ /* RootScriptStructureElement */var x: Int/* DeclarationStructureElement */
get() = field get() = field
set(value) { set(value) {
field = value field = value
} }
val y = 42/* NonReanalyzableNonClassDeclarationStructureElement */ val y = 42/* DeclarationStructureElement */
var z: Int = 15/* NonReanalyzableNonClassDeclarationStructureElement */ var z: Int = 15/* DeclarationStructureElement */
@@ -1,4 +1,4 @@
fun foo() {/* ReanalyzableFunctionStructureElement */ fun foo() {/* DeclarationStructureElement */
println("") println("")
} }
@@ -1,3 +1,3 @@
/* RootScriptStructureElement */fun foo() {/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun foo() {/* DeclarationStructureElement */
println("") println("")
} }
@@ -1 +1 @@
typealias A = 10/* NonReanalyzableNonClassDeclarationStructureElement */ typealias A = 10/* DeclarationStructureElement */
@@ -1,27 +1,27 @@
fun (a: Int = 1): String = "str"/* ReanalyzableFunctionStructureElement */ fun (a: Int = 1): String = "str"/* DeclarationStructureElement */
fun () {/* ReanalyzableFunctionStructureElement */ fun () {/* DeclarationStructureElement */
} }
val : Int = 4/* NonReanalyzableNonClassDeclarationStructureElement */ val : Int = 4/* DeclarationStructureElement */
var : Int/* ReanalyzablePropertyStructureElement */ var : Int/* DeclarationStructureElement */
get() = 4 get() = 4
set(value) { set(value) {
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun (a: Int = 1): String = "str"/* ReanalyzableFunctionStructureElement */ fun (a: Int = 1): String = "str"/* DeclarationStructureElement */
fun () {/* ReanalyzableFunctionStructureElement */ fun () {/* DeclarationStructureElement */
} }
val : Int = 4/* NonReanalyzableNonClassDeclarationStructureElement */ val : Int = 4/* DeclarationStructureElement */
var : Boolean/* ReanalyzablePropertyStructureElement */ var : Boolean/* DeclarationStructureElement */
get() = true get() = true
set(value) { set(value) {
@@ -1,27 +1,27 @@
/* RootScriptStructureElement */fun (a: Int = 1): String = "str"/* ReanalyzableFunctionStructureElement */ /* RootScriptStructureElement */fun (a: Int = 1): String = "str"/* DeclarationStructureElement */
fun () {/* ReanalyzableFunctionStructureElement */ fun () {/* DeclarationStructureElement */
} }
val : Int = 4/* NonReanalyzableNonClassDeclarationStructureElement */ val : Int = 4/* DeclarationStructureElement */
var : Int/* ReanalyzablePropertyStructureElement */ var : Int/* DeclarationStructureElement */
get() = 4 get() = 4
set(value) { set(value) {
} }
class A {/* NonReanalyzableClassDeclarationStructureElement */ class A {/* ClassDeclarationStructureElement */
fun (a: Int = 1): String = "str"/* ReanalyzableFunctionStructureElement */ fun (a: Int = 1): String = "str"/* DeclarationStructureElement */
fun () {/* ReanalyzableFunctionStructureElement */ fun () {/* DeclarationStructureElement */
} }
val : Int = 4/* NonReanalyzableNonClassDeclarationStructureElement */ val : Int = 4/* DeclarationStructureElement */
var : Boolean/* ReanalyzablePropertyStructureElement */ var : Boolean/* DeclarationStructureElement */
get() = true get() = true
set(value) { set(value) {
@@ -55,19 +55,13 @@ abstract class AbstractFirContextCollectionTest : AbstractLowLevelApiSingleFileT
val fileStructure = fileStructureCache.getFileStructure(ktFile) val fileStructure = fileStructureCache.getFileStructure(ktFile)
val allStructureElements = fileStructure.getAllStructureElements() val allStructureElements = fileStructure.getAllStructureElements()
handler.elementsToCheckContext = allStructureElements.map { it.getFirDeclaration() } handler.elementsToCheckContext = allStructureElements.map(FileStructureElement::firDeclaration)
handler.firFile = ktFile.getOrBuildFirFile(firResolveSession) handler.firFile = ktFile.getOrBuildFirFile(firResolveSession)
ktFile.getDiagnostics(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS) ktFile.getDiagnostics(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
} }
} }
private fun FileStructureElement.getFirDeclaration(): FirDeclaration = when (this) {
is RootStructureElement -> firFile
is ReanalyzableStructureElement<*, *> -> firSymbol.fir
is NonReanalyzableDeclarationStructureElement<*> -> firDeclaration
}
private class BeforeElementLLFirSessionConfigurator(private val testServices: TestServices) : LLFirSessionConfigurator { private class BeforeElementLLFirSessionConfigurator(private val testServices: TestServices) : LLFirSessionConfigurator {
@OptIn(SessionConfiguration::class) @OptIn(SessionConfiguration::class)
override fun configure(session: LLFirSession) { override fun configure(session: LLFirSession) {
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.Analys
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirScriptTestConfigurator import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirScriptTestConfigurator
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
@@ -29,8 +31,7 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) { override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val fileStructure = ktFile.getFileStructure() val fileStructure = ktFile.getFileStructure()
val allStructureElements = fileStructure.getAllStructureElements(ktFile) val allStructureElements = fileStructure.getAllStructureElements(ktFile)
val declarationToStructureElement = allStructureElements.associateBy { it.psi } val declarationToStructureElement = allStructureElements.associateBy { it.firDeclaration.psi }
val elementToComment = mutableMapOf<PsiElement, String>() val elementToComment = mutableMapOf<PsiElement, String>()
ktFile.forEachDescendantOfType<KtDeclaration> { ktDeclaration -> ktFile.forEachDescendantOfType<KtDeclaration> { ktDeclaration ->
val structureElement = declarationToStructureElement[ktDeclaration] ?: return@forEachDescendantOfType val structureElement = declarationToStructureElement[ktDeclaration] ?: return@forEachDescendantOfType
@@ -76,7 +77,7 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
PsiTreeUtil.getChildrenOfTypeAsList(ktFile, KtModifierList::class.java).forEach { PsiTreeUtil.getChildrenOfTypeAsList(ktFile, KtModifierList::class.java).forEach {
if (it.nextSibling is PsiErrorElement) { if (it.nextSibling is PsiErrorElement) {
val structureElement = declarationToStructureElement[ktFile] ?: return@forEach val structureElement = declarationToStructureElement[it] ?: return@forEach
val comment = structureElement.createComment() val comment = structureElement.createComment()
elementToComment[it] = comment elementToComment[it] = comment
} }
@@ -120,6 +121,12 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
} }
} }
internal val FileStructureElement.firDeclaration: FirDeclaration
get() = when (this) {
is RootStructureElement -> file
is DeclarationBaseStructureElement<*> -> declaration
}
abstract class AbstractSourceFileStructureTest : AbstractFileStructureTest() { abstract class AbstractSourceFileStructureTest : AbstractFileStructureTest() {
override val configurator = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false) override val configurator = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false)
} }