From 327208fb8a0ab1742edba30b69e7b2ca4b584ff2 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Thu, 23 Feb 2023 17:43:13 +0100 Subject: [PATCH] [SLC] drop hard references to member declarations to reduce memory consumption ^KT-56613 Fixed --- .../classes/SymbolLightClassForAnnotationClass.kt | 5 ++--- .../classes/SymbolLightClassForAnonymousObject.kt | 8 +++----- .../symbol/classes/SymbolLightClassForClassLike.kt | 4 +--- .../classes/SymbolLightClassForClassOrObject.kt | 7 +++---- .../symbol/classes/SymbolLightClassForEnumEntry.kt | 13 ++++++------- .../symbol/classes/SymbolLightClassForFacade.kt | 7 +++---- .../classes/SymbolLightClassForInlineClass.kt | 10 +++------- .../symbol/classes/SymbolLightClassForInterface.kt | 6 ++---- ...SymbolLightClassForInterfaceOrAnnotationClass.kt | 5 ++--- .../symbol/fields/SymbolLightFieldForEnumEntry.kt | 6 +++--- .../kotlin/light/classes/symbol/symbolLightUtils.kt | 9 +++++++++ 11 files changed, 37 insertions(+), 43 deletions(-) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt index 828551407ca..9a0c1fd7546 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt @@ -14,8 +14,8 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThis import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject @@ -62,11 +62,10 @@ internal open class SymbolLightClassForAnnotationClass : SymbolLightClassForInte result } - private val _ownMethods: List by lazyPub { + final override fun getOwnMethods(): List = cachedValue { computeOwnMethods() } - final override fun getOwnMethods(): List = _ownMethods override fun getExtendsList(): PsiReferenceList? = null final override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt index 97ee65f60ae..4f0e85f2fce 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.psi.KtClassOrObject @@ -65,10 +66,7 @@ internal class SymbolLightClassForAnonymousObject : SymbolLightClassForClassLike override fun getExtendsList(): PsiReferenceList? = _extendsList override fun getImplementsList(): PsiReferenceList? = _implementsList - override fun getOwnFields(): List = _ownFields - override fun getOwnMethods(): List = _ownMethods - - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { withClassOrObjectSymbol { val result = mutableListOf() val declaredMemberScope = it.getDeclaredMemberScope() @@ -79,7 +77,7 @@ internal class SymbolLightClassForAnonymousObject : SymbolLightClassForClassLike } } - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { val result = mutableListOf() val nameGenerator = SymbolLightField.FieldNameGenerator() 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 0da7f0c3f73..465a83fe3ea 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 @@ -102,14 +102,12 @@ abstract class SymbolLightClassForClassLike prote override fun getTypeParameters(): Array = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY - private val _ownInnerClasses: List by lazyPub { + override fun getOwnInnerClasses(): List = cachedValue { withClassOrObjectSymbol { it.createInnerClasses(manager, this@SymbolLightClassForClassLike, classOrObjectDeclaration) } } - override fun getOwnInnerClasses(): List = _ownInnerClasses - override fun getTextOffset(): Int = classOrObjectDeclaration?.textOffset ?: -1 override fun getStartOffsetInParent(): Int = classOrObjectDeclaration?.startOffsetInParent ?: -1 diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt index 6626285d21f..6beb2e82f7e 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightSimpleMethod @@ -92,8 +93,6 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC } override fun getModifierList(): PsiModifierList? = _modifierList - override fun getOwnFields(): List = _ownFields - override fun getOwnMethods(): List = _ownMethods override fun getExtendsList(): PsiReferenceList? = _extendsList override fun getImplementsList(): PsiReferenceList? = _implementsList @@ -109,7 +108,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC } } - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() @@ -241,7 +240,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC } } - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt index 7ec58fc3572..8f68baa0d78 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.codeReferences.SymbolLightPsiJavaCodeReferenceElementWithNoReference import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.isOriginEquivalentTo @@ -23,7 +24,7 @@ import org.jetbrains.kotlin.psi.KtEnumEntry internal class SymbolLightClassForEnumEntry( private val enumConstant: SymbolLightFieldForEnumEntry, - private val enumClass: SymbolLightClassForClassOrObject, + private val enumClass: SymbolLightClassBase, ktModule: KtModule, ) : SymbolLightClassBase(ktModule, enumConstant.manager), PsiEnumConstantInitializer { override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO @@ -100,7 +101,7 @@ internal class SymbolLightClassForEnumEntry( override fun getScope(): PsiElement = parent - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { enumConstant.withEnumEntrySymbol { enumEntrySymbol -> val result = mutableListOf() @@ -111,9 +112,7 @@ internal class SymbolLightClassForEnumEntry( } } - override fun getOwnFields(): List = _ownFields - - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { enumConstant.withEnumEntrySymbol { enumEntrySymbol -> val result = mutableListOf() @@ -127,8 +126,8 @@ internal class SymbolLightClassForEnumEntry( } } - override fun getOwnMethods(): List = _ownMethods - override fun getOwnInnerClasses(): MutableList = mutableListOf() + override fun getOwnInnerClasses(): List = emptyList() + override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean { if (!checkDeep) return baseClass == enumClass diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt index 4798433d753..64a08940316 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fileClasses.isJvmMultifileClassFile import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses import org.jetbrains.kotlin.light.classes.symbol.annotations.* +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.light.classes.symbol.modifierLists.InitializedModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList @@ -80,8 +81,7 @@ internal class SymbolLightClassForFacade( override fun getScope(): PsiElement = parent - override fun getOwnMethods(): List = _ownMethods - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { withFileSymbols { fileSymbols -> val result = mutableListOf() val methodsAndProperties = sequence { @@ -136,8 +136,7 @@ internal class SymbolLightClassForFacade( private fun KtPropertyAccessorSymbol?.isNullOrPublic(): Boolean = this?.toPsiVisibilityForMember()?.let { it == PsiModifier.PUBLIC } != false - override fun getOwnFields(): List = _ownFields - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { val result = mutableListOf() val nameGenerator = SymbolLightField.FieldNameGenerator() withFileSymbols { fileSymbols -> diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInlineClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInlineClass.kt index 51671aa29a9..6e58ae5f92b 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInlineClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInlineClass.kt @@ -13,10 +13,10 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue @@ -45,7 +45,7 @@ internal class SymbolLightClassForInlineClass : SymbolLightClassForClassOrObject manager = manager, ) - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() @@ -82,7 +82,7 @@ internal class SymbolLightClassForInlineClass : SymbolLightClassForClassOrObject } } - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> mutableListOf().apply { addPropertyBackingFields(this, classOrObjectSymbol) @@ -90,10 +90,6 @@ internal class SymbolLightClassForInlineClass : SymbolLightClassForClassOrObject } } - override fun getOwnMethods(): List = _ownMethods - - override fun getOwnFields(): List = _ownFields - override fun copy(): SymbolLightClassForInlineClass = SymbolLightClassForInlineClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt index 16a5f93b83c..5be600fa49d 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject @@ -52,7 +53,7 @@ internal open class SymbolLightClassForInterface : SymbolLightClassForInterfaceO manager = manager, ) - private val _ownMethods: List by lazyPub { + override fun getOwnMethods(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() @@ -69,9 +70,6 @@ internal open class SymbolLightClassForInterface : SymbolLightClassForInterfaceO protected open fun acceptCallableSymbol(symbol: KtCallableSymbol): Boolean = !(symbol is KtFunctionSymbol && symbol.visibility.isPrivateOrPrivateToThis() || symbol.hasTypeForValueClassInSignature()) - - override fun getOwnMethods(): List = _ownMethods - override fun copy(): SymbolLightClassForInterface = SymbolLightClassForInterface(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt index ab471c6531e..d325eb5fe7f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.light.classes.symbol.annotations.AbstractClassAdditionalAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.modifierLists.GranularModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with @@ -84,7 +85,7 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi final override fun getModifierList(): PsiModifierList? = _modifierList - private val _ownFields: List by lazyPub { + override fun getOwnFields(): List = cachedValue { withClassOrObjectSymbol { classOrObjectSymbol -> buildList { addCompanionObjectFieldIfNeeded(this, classOrObjectSymbol) @@ -93,7 +94,5 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi } } - override fun getOwnFields(): List = _ownFields - override fun getImplementsList(): PsiReferenceList? = null } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt index e8d9c125952..4612bec6d41 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses import org.jetbrains.kotlin.light.classes.symbol.annotations.GranularAnnotationsBox import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolAnnotationsProvider import org.jetbrains.kotlin.light.classes.symbol.annotations.annotationUseSiteTargetFilterOf +import org.jetbrains.kotlin.light.classes.symbol.cachedValue import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassOrObject import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.isOriginEquivalentTo @@ -67,7 +68,7 @@ internal class SymbolLightFieldForEnumEntry( private val hasBody: Boolean get() = enumEntry.body != null - private val _initializingClass: PsiEnumConstantInitializer? by lazyPub { + override fun getInitializingClass(): PsiEnumConstantInitializer? = cachedValue { hasBody.ifTrue { SymbolLightClassForEnumEntry( enumConstant = this@SymbolLightFieldForEnumEntry, @@ -77,8 +78,7 @@ internal class SymbolLightFieldForEnumEntry( } } - override fun getInitializingClass(): PsiEnumConstantInitializer? = _initializingClass - override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = _initializingClass ?: cannotModify() + override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = initializingClass ?: cannotModify() override fun getArgumentList(): PsiExpressionList? = null override fun resolveMethod(): PsiMethod? = null 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 0107b28a910..87a10ab8c92 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 @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.light.classes.symbol import com.intellij.psi.* +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.TypeConversionUtil import com.intellij.util.IncorrectOperationException import org.jetbrains.kotlin.analysis.api.KtAnalysisSession @@ -21,6 +23,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.types.* import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightMember @@ -271,3 +274,9 @@ internal val KtPropertySymbol.isLateInit: Boolean get() = (this as? KtKotlinProp internal inline fun Collection.toArrayIfNotEmptyOrDefault(default: Array): Array { return if (isNotEmpty()) toTypedArray() else default } + +internal inline fun R.cachedValue( + crossinline computer: () -> T, +): T = CachedValuesManager.getCachedValue(this) { + CachedValueProvider.Result.createSingleDependency(computer(), project.createProjectWideOutOfBlockModificationTracker()) +}