diff --git a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt index c3297c01ff3..25108b0de56 100644 --- a/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt +++ b/analysis/decompiled/light-classes-for-decompiled/src/org/jetbrains/kotlin/analysis/decompiled/light/classes/KtLightClassForDecompiledDeclaration.kt @@ -44,7 +44,7 @@ open class KtLightClassForDecompiledDeclaration( ClassInnerStuffCache( /* aClass = */ this, /* generateEnumMethods = */ true, - /* modificationTracker = */ project.createAllLibrariesModificationTracker(), + /* modificationTrackers = */ listOf(project.createAllLibrariesModificationTracker()), ) } diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/ClassInnerStuffCache.java b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/ClassInnerStuffCache.java index fd1bad803c2..fced2195bf7 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/ClassInnerStuffCache.java +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/ClassInnerStuffCache.java @@ -50,27 +50,27 @@ public final class ClassInnerStuffCache { public static final String NOT_NULL_ANNOTATION_QUALIFIER = "@" + NotNull.class.getName(); private final @NotNull KtExtensibleLightClass myClass; - private final @NotNull ModificationTracker myModificationTracker; + private final @NotNull List myModificationTrackers; private final @NotNull Ref>> myInterner = Ref.create(); private final boolean myGenerateEnumMethods; public ClassInnerStuffCache( @NotNull KtExtensibleLightClass aClass, boolean generateEnumMethods, - @NotNull ModificationTracker modificationTracker + @NotNull List modificationTrackers ) { myGenerateEnumMethods = generateEnumMethods; myClass = aClass; - myModificationTracker = modificationTracker; + myModificationTrackers = modificationTrackers; } @NotNull public PsiMethod[] getConstructors() { return copy(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( PsiImplUtil.getConstructors(myClass), - myModificationTracker + myModificationTrackers ) )); } @@ -79,9 +79,9 @@ public final class ClassInnerStuffCache { public PsiField[] getFields() { return copy(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( calcFields(), - myModificationTracker + myModificationTrackers ) )); } @@ -90,9 +90,9 @@ public final class ClassInnerStuffCache { public PsiMethod[] getMethods() { return copy(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( calcMethods(), - myModificationTracker + myModificationTrackers ) )); } @@ -101,9 +101,9 @@ public final class ClassInnerStuffCache { public PsiClass[] getInnerClasses() { return copy(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( calcInnerClasses(), - myModificationTracker + myModificationTrackers ) )); } @@ -116,9 +116,9 @@ public final class ClassInnerStuffCache { else { return CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( getFieldsMap(), - myModificationTracker + myModificationTrackers ) ).get(name); } @@ -132,9 +132,9 @@ public final class ClassInnerStuffCache { else { return copy(notNull(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( getMethodsMap(), - myModificationTracker + myModificationTrackers ) ).get(name), PsiMethod.EMPTY_ARRAY)); } @@ -148,9 +148,9 @@ public final class ClassInnerStuffCache { else { return CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( getInnerClassesMap(), - myModificationTracker + myModificationTrackers ) ).get(name); } @@ -160,9 +160,9 @@ public final class ClassInnerStuffCache { private PsiMethod getValuesMethod() { return isEnum() ? internMember(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( makeValuesMethod(myClass), - myModificationTracker + myModificationTrackers ) )) : null; } @@ -171,9 +171,9 @@ public final class ClassInnerStuffCache { private PsiMethod getValueOfMethod() { return isEnum() ? internMember(CachedValuesManager.getCachedValue( myClass, - () -> CachedValueProvider.Result.createSingleDependency( + () -> CachedValueProvider.Result.create( makeValueOfMethod(myClass), - myModificationTracker + myModificationTrackers ) )) : null; } @@ -201,7 +201,11 @@ public final class ClassInnerStuffCache { @SuppressWarnings("unchecked") private T internMember(T m) { if (m == null) return null; - long modCount = myModificationTracker.getModificationCount(); + long modCount = 0; + for (ModificationTracker tracker : myModificationTrackers) { + modCount += tracker.getModificationCount(); + } + synchronized (myInterner) { Pair> pair = myInterner.get(); if (pair == null || pair.first.longValue() != modCount) { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt index 38eaf758df3..816a656e559 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.navigation.ItemPresentation import com.intellij.navigation.ItemPresentationProviders +import com.intellij.openapi.util.ModificationTracker import com.intellij.openapi.util.Pair import com.intellij.openapi.util.TextRange import com.intellij.psi.* @@ -37,10 +38,14 @@ abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule ClassInnerStuffCache( /* aClass = */ this, /* generateEnumMethods = */ false, - /* modificationTracker = */ project.createProjectWideOutOfBlockModificationTracker(), + /* modificationTrackers = */ modificationTrackerForClassInnerStuff(), ) } + protected open fun modificationTrackerForClassInnerStuff(): List { + return listOf(project.createProjectWideOutOfBlockModificationTracker()) + } + override fun getFields(): Array = myInnersCache.fields override fun getMethods(): Array = myInnersCache.methods diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt index 52411131a4d..11d2a544ced 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.openapi.util.ModificationTracker import com.intellij.psi.* import com.intellij.psi.impl.InheritanceImplUtil import com.intellij.psi.impl.PsiClassImplUtil @@ -56,6 +57,10 @@ abstract class SymbolLightClassForClassLike prote manager = manager, ) + override fun modificationTrackerForClassInnerStuff(): List { + return classOrObjectDeclaration?.modificationTrackerForClassInnerStuff() ?: super.modificationTrackerForClassInnerStuff() + } + override val kotlinOrigin: KtClassOrObject? get() = classOrObjectDeclaration internal inline fun withClassOrObjectSymbol(crossinline action: KtAnalysisSession.(SType) -> T): T = diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index cbd8da7856e..2cc7427ba2f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.openapi.util.ModificationTracker import com.intellij.psi.PsiElement import com.intellij.psi.PsiManager import com.intellij.psi.PsiModifier @@ -22,6 +23,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.analysis.utils.printer.parentOfType import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration @@ -68,6 +70,16 @@ internal fun createLightClassNoCache(ktClassOrObject: KtClassOrObject, ktModule: else -> SymbolLightClassForClassOrObject(ktClassOrObject, ktModule) } +internal fun KtClassOrObject.modificationTrackerForClassInnerStuff(): List { + val outOfBlockTracker = project.createProjectWideOutOfBlockModificationTracker() + return if (isLocal) { + val file = containingKtFile + listOf(outOfBlockTracker, ModificationTracker { file.modificationStamp }) + } else { + listOf(outOfBlockTracker) + } +} + context(KtAnalysisSession) internal fun createLightClassNoCache( ktClassOrObjectSymbol: KtNamedClassOrObjectSymbol, diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt index 785d7587098..5ac31c248bd 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/symbolLightUtils.kt @@ -32,8 +32,10 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassLike import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterface import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForInterfaceDefaultImpls +import org.jetbrains.kotlin.light.classes.symbol.classes.modificationTrackerForClassInnerStuff import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.KtTypeParameterListOwner @@ -324,5 +326,11 @@ internal inline fun Collection.toArrayIfNotEmptyOrDefault(default internal inline fun R.cachedValue( crossinline computer: () -> T, ): T = CachedValuesManager.getCachedValue(this) { - CachedValueProvider.Result.createSingleDependency(computer(), project.createProjectWideOutOfBlockModificationTracker()) + val value = computer() + val specialClassTrackers = (this as? SymbolLightClassForClassLike<*>)?.classOrObjectDeclaration?.modificationTrackerForClassInnerStuff() + if (specialClassTrackers != null) { + CachedValueProvider.Result.create(value, specialClassTrackers) + } else { + CachedValueProvider.Result.createSingleDependency(value, project.createProjectWideOutOfBlockModificationTracker()) + } }