[lc] KotlinAsJavaSupportBase: introduce LightClassCachedValue
to extract common logic with cached values ^KT-50241
This commit is contained in:
+22
-17
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
|
|
||||||
abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project) : KotlinAsJavaSupport() {
|
abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project) : KotlinAsJavaSupport() {
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
fun createLightFacade(file: KtFile): Pair<KtLightClassForFacade?, ModificationTracker>? {
|
fun createLightFacade(file: KtFile): LightClassCachedValue<KtLightClassForFacade>? {
|
||||||
if (!file.facadeIsPossible()) return null
|
if (!file.facadeIsPossible()) return null
|
||||||
|
|
||||||
val module = file.findModule().takeIf { facadeIsApplicable(it, file) } ?: return null
|
val module = file.findModule().takeIf { facadeIsApplicable(it, file) } ?: return null
|
||||||
@@ -37,11 +37,11 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
return when {
|
return when {
|
||||||
facadeFiles.none(KtFile::hasTopLevelCallables) -> null
|
facadeFiles.none(KtFile::hasTopLevelCallables) -> null
|
||||||
facadeFiles.none(KtFile::isCompiled) -> {
|
facadeFiles.none(KtFile::isCompiled) -> {
|
||||||
createInstanceOfLightFacade(facadeFqName, facadeFiles) to outOfBlockModificationTracker(file)
|
LightClassCachedValue(createInstanceOfLightFacade(facadeFqName, facadeFiles), outOfBlockModificationTracker(file))
|
||||||
}
|
}
|
||||||
|
|
||||||
facadeFiles.all(KtFile::isCompiled) -> {
|
facadeFiles.all(KtFile::isCompiled) -> {
|
||||||
createInstanceOfDecompiledLightFacade(facadeFqName, facadeFiles) to librariesTracker(file)
|
LightClassCachedValue(createInstanceOfDecompiledLightFacade(facadeFqName, facadeFiles), librariesTracker(file))
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> error("Source and compiled files are mixed: $facadeFiles")
|
else -> error("Source and compiled files are mixed: $facadeFiles")
|
||||||
@@ -79,8 +79,7 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
|
|
||||||
override fun getLightFacade(file: KtFile): KtLightClassForFacade? = ifValid(file) {
|
override fun getLightFacade(file: KtFile): KtLightClassForFacade? = ifValid(file) {
|
||||||
CachedValuesManager.getCachedValue(file) {
|
CachedValuesManager.getCachedValue(file) {
|
||||||
val (facade, tracker) = createLightFacade(file) ?: (null to projectWideOutOfBlockModificationTracker())
|
cachedValueResult(createLightFacade(file))
|
||||||
CachedValueProvider.Result.createSingleDependency(facade, tracker)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,17 +127,17 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
fun createLightClass(classOrObject: KtClassOrObject): Pair<KtLightClass?, ModificationTracker>? {
|
fun createLightClass(classOrObject: KtClassOrObject): LightClassCachedValue<KtLightClass>? {
|
||||||
if (classOrObject.shouldNotBeVisibleAsLightClass()) return null
|
if (classOrObject.shouldNotBeVisibleAsLightClass()) return null
|
||||||
|
|
||||||
val containingFile = classOrObject.containingKtFile
|
val containingFile = classOrObject.containingKtFile
|
||||||
when (declarationLocation(containingFile)) {
|
when (declarationLocation(containingFile)) {
|
||||||
DeclarationLocation.ProjectSources -> {
|
DeclarationLocation.ProjectSources -> {
|
||||||
return createInstanceOfLightClass(classOrObject) to outOfBlockModificationTracker(classOrObject)
|
return LightClassCachedValue(createInstanceOfLightClass(classOrObject), outOfBlockModificationTracker(classOrObject))
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationLocation.LibraryClasses -> {
|
DeclarationLocation.LibraryClasses -> {
|
||||||
return createInstanceOfDecompiledLightClass(classOrObject) to librariesTracker(classOrObject)
|
return LightClassCachedValue(createInstanceOfDecompiledLightClass(classOrObject), librariesTracker(classOrObject))
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationLocation.LibrarySources -> {
|
DeclarationLocation.LibrarySources -> {
|
||||||
@@ -150,14 +149,14 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
guardedRun { getLightClass(it) }
|
guardedRun { getLightClass(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return value to librariesTracker(classOrObject)
|
return LightClassCachedValue(value, librariesTracker(classOrObject))
|
||||||
}
|
}
|
||||||
|
|
||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containingFile.analysisContext != null || containingFile.originalFile.virtualFile != null) {
|
if (containingFile.analysisContext != null || containingFile.originalFile.virtualFile != null) {
|
||||||
return createInstanceOfLightClass(classOrObject) to outOfBlockModificationTracker(classOrObject)
|
return LightClassCachedValue(createInstanceOfLightClass(classOrObject), outOfBlockModificationTracker(classOrObject))
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
@@ -173,33 +172,39 @@ abstract class KotlinAsJavaSupportBase<TModule>(protected val project: Project)
|
|||||||
|
|
||||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = ifValid(classOrObject) {
|
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = ifValid(classOrObject) {
|
||||||
CachedValuesManager.getCachedValue(classOrObject) {
|
CachedValuesManager.getCachedValue(classOrObject) {
|
||||||
val (clazz, tracker) = createLightClass(classOrObject) ?: (null to projectWideOutOfBlockModificationTracker())
|
cachedValueResult(createLightClass(classOrObject))
|
||||||
CachedValueProvider.Result.createSingleDependency(clazz, tracker)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
fun createLightScript(script: KtScript): Pair<KtLightClass?, ModificationTracker>? {
|
fun createLightScript(script: KtScript): LightClassCachedValue<KtLightClass>? {
|
||||||
val containingFile = script.containingFile
|
val containingFile = script.containingFile
|
||||||
if (containingFile is KtCodeFragment) {
|
if (containingFile is KtCodeFragment) {
|
||||||
// Avoid building light classes for code fragments
|
// Avoid building light classes for code fragments
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return createInstanceOfLightScript(script) to projectWideOutOfBlockModificationTracker()
|
return LightClassCachedValue(createInstanceOfLightScript(script), projectWideOutOfBlockModificationTracker())
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun createInstanceOfLightScript(script: KtScript): KtLightClass?
|
protected abstract fun createInstanceOfLightScript(script: KtScript): KtLightClass?
|
||||||
|
|
||||||
override fun getLightClassForScript(script: KtScript): KtLightClass? = ifValid(script) {
|
override fun getLightClassForScript(script: KtScript): KtLightClass? = ifValid(script) {
|
||||||
CachedValuesManager.getCachedValue(script) {
|
CachedValuesManager.getCachedValue(script) {
|
||||||
val (lightScript, tracker) = createLightScript(script) ?: (null to projectWideOutOfBlockModificationTracker())
|
cachedValueResult(createLightScript(script))
|
||||||
CachedValueProvider.Result.createSingleDependency(lightScript, tracker)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T : KtLightClass> cachedValueResult(lightClassCachedValue: LightClassCachedValue<T>?): CachedValueProvider.Result<T> {
|
||||||
|
val value = lightClassCachedValue?.value
|
||||||
|
val tracker = lightClassCachedValue?.tracker ?: projectWideOutOfBlockModificationTracker()
|
||||||
|
return CachedValueProvider.Result.createSingleDependency(value, tracker)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <T : PsiElement, V> ifValid(element: T, action: () -> V?): V? {
|
private inline fun <T : PsiElement, V> ifValid(element: T, action: () -> V?): V? {
|
||||||
if (!element.isValid) return null
|
if (!element.isValid) return null
|
||||||
return action()
|
return action()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LightClassCachedValue<T : KtLightClass>(val value: T?, val tracker: ModificationTracker)
|
||||||
|
|||||||
Reference in New Issue
Block a user