diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt index eed58eea194..742dafe756b 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/FacadeCache.kt @@ -31,33 +31,10 @@ private data class ValueWrapper(val value: KtLightClassForFacade?) { class FacadeCache(private val project: Project) { private inner class FacadeCacheData { val cache = object : SLRUCache(20, 30) { - override fun createValue(key: StubCacheKey): ValueWrapper { - - val (fqName, searchScope) = key - - val sources = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(key.fqName, key.searchScope) - .filterNot { it.isCompiled } - - if (sources.isEmpty()) return ValueWrapper.Null - - val ultraLightEnabled = - !KtUltraLightSupport.forceUsingOldLightClasses && Registry.`is`("kotlin.use.ultra.light.classes", true) - - val stubProvider = LightClassDataProviderForFileFacade.ByProjectSource(project, fqName, searchScope) - val stubValue = CachedValuesManager.getManager(project) - .createCachedValue(stubProvider, false) - - val manager = PsiManager.getInstance(project) - - val ultraLightClass = if (ultraLightEnabled) - LightClassGenerationSupport.getInstance(project) - .createUltraLightClassForFacade(manager, fqName, stubValue, sources) - else null - - val result = ultraLightClass ?: KtLightClassForFacade(manager, fqName, stubValue, sources) - - return ValueWrapper(result) - } + override fun createValue(key: StubCacheKey): ValueWrapper = + KtLightClassForFacade.createForFacadeNoCache(key.fqName, key.searchScope, project) + ?.let { ValueWrapper(it) } + ?: ValueWrapper.Null } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt index cf0e04eaf68..36142391b88 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForFacade.kt @@ -16,8 +16,11 @@ package org.jetbrains.kotlin.asJava.classes +import com.google.common.annotations.VisibleForTesting +import com.intellij.openapi.project.Project import com.intellij.openapi.util.Comparing import com.intellij.openapi.util.TextRange +import com.intellij.openapi.util.registry.Registry import com.intellij.psi.* import com.intellij.psi.impl.light.LightEmptyImplementsList import com.intellij.psi.impl.light.LightModifierList @@ -25,6 +28,8 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValuesManager import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport +import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass @@ -44,10 +49,26 @@ import javax.swing.Icon open class KtLightClassForFacade constructor( manager: PsiManager, protected val facadeClassFqName: FqName, - protected open val lightClassDataCache: CachedValue, + myLightClassDataCache: CachedValue, files: Collection ) : KtLazyLightClass(manager) { + @Volatile + @VisibleForTesting + var isClsDelegateLoaded = false + + override val clsDelegate: PsiClass + get() { + isClsDelegateLoaded = true + return super.clsDelegate + } + + protected open val lightClassDataCache: CachedValue = myLightClassDataCache + get() { + isClsDelegateLoaded = true + return field + } + val files: Collection = files.toSet() private val firstFileInFacade by lazyPub { files.iterator().next() } @@ -240,12 +261,37 @@ open class KtLightClassForFacade constructor( override fun isWritable() = firstFileInFacade.isWritable companion object { + + fun createForFacadeNoCache(fqName: FqName, searchScope: GlobalSearchScope, project: Project): KtLightClassForFacade? { + + val sources = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(fqName, searchScope) + .filterNot { it.isCompiled } + + if (sources.isEmpty()) return null + + val ultraLightEnabled = + !KtUltraLightSupport.forceUsingOldLightClasses && Registry.`is`("kotlin.use.ultra.light.classes", true) + + val stubProvider = LightClassDataProviderForFileFacade.ByProjectSource(project, fqName, searchScope) + val stubValue = CachedValuesManager.getManager(project) + .createCachedValue(stubProvider, false) + + val manager = PsiManager.getInstance(project) + + val ultraLightClass = if (ultraLightEnabled) + LightClassGenerationSupport.getInstance(project) + .createUltraLightClassForFacade(manager, fqName, stubValue, sources) + else null + + return ultraLightClass ?: KtLightClassForFacade(manager, fqName, stubValue, sources) + } + fun createForFacade( manager: PsiManager, facadeClassFqName: FqName, searchScope: GlobalSearchScope ): KtLightClassForFacade? { - return FacadeCache.getInstance(manager.project).get(facadeClassFqName, searchScope) + return FacadeCache.getInstance(manager.project)[facadeClassFqName, searchScope] } fun createForSyntheticFile( diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt index b9243ada0af..44881eca4db 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraKtLightClassForFacade.kt @@ -11,7 +11,6 @@ import com.intellij.psi.util.CachedValue import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod -import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction @@ -22,7 +21,7 @@ class KtUltraLightClassForFacade( facadeClassFqName: FqName, lightClassDataCache: CachedValue, files: Collection, - private val filesToSupports: Collection> + private val filesWithSupports: Collection> ) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) { private inline fun forTooComplex(getter: () -> T): T { @@ -43,38 +42,61 @@ class KtUltraLightClassForFacade( override fun getScope(): PsiElement? = if (!tooComplex) parent else super.getScope() private val tooComplex: Boolean by lazyPub { - filesToSupports.any { (file, support) -> + filesWithSupports.any { (file, support) -> file.declarations.any { support.isTooComplexForUltraLightGeneration(it) } } } - private val filesToSupportsToMemberCreators by lazyPub { - filesToSupports.map { (file, support) -> - Triple(file, support, UltraLightMembersCreator(this, false, true, support)) + private val filesWithSupportsWithCreators by lazyPub { + filesWithSupports.map { (file, support) -> + Triple( + file, + support, + UltraLightMembersCreator( + containingClass = this, + containingClassIsNamedObject = false, + containingClassIsSealed = true, + mangleInternalFunctions = false, + support = support + ) + ) + } + } + + private fun loadMethodsFromFile( + file: KtFile, + support: KtUltraLightSupport, + creator: UltraLightMembersCreator, + result: MutableList + ) { + for (declaration in file.declarations.filterNot { it.isHiddenByDeprecation(support) }) { + when (declaration) { + is KtNamedFunction -> result.addAll(creator.createMethods(declaration, true)) + is KtProperty -> { + result.addAll( + creator.propertyAccessors( + declaration, declaration.isVar, + forceStatic = true, + onlyJvmStatic = false + ) + ) + + } + } } } private val ownMethodsForNotTooComplex: List by lazyPub { - - val result = arrayListOf() - - for ((file, support, creator) in filesToSupportsToMemberCreators) { - - for (declaration in file.declarations.filterNot { it.isHiddenByDeprecation(support) }) { - if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue - when (declaration) { - is KtNamedFunction -> result.addAll(creator.createMethods(declaration, true)) - is KtProperty -> result.addAll(creator.propertyAccessors(declaration, declaration.isVar, true, false)) - } + mutableListOf().also { result -> + for ((file, support, creator) in filesWithSupportsWithCreators) { + loadMethodsFromFile(file, support, creator, result) } } - - result } private val ownFieldsForNotTooComplex: List by lazyPub { hashSetOf().let { nameCache -> - filesToSupportsToMemberCreators.flatMap { (file, _, creator) -> + filesWithSupportsWithCreators.flatMap { (file, _, creator) -> file.declarations.filterIsInstance().mapNotNull { creator.createPropertyField(it, nameCache, forceStatic = true) } @@ -89,5 +111,5 @@ class KtUltraLightClassForFacade( override fun getVisibleSignatures(): MutableCollection = PsiSuperMethodImplUtil.getVisibleSignatures(this) override fun copy(): KtLightClassForFacade = - KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesToSupports) + KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesWithSupports) } \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index 4e78b205f6f..19f2f7c0830 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -40,7 +40,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor KtLightClassImpl(classOrObject) { private val membersBuilder by lazyPub { - UltraLightMembersCreator(this, isNamedObject(), classOrObject.hasModifier(SEALED_KEYWORD), support) + UltraLightMembersCreator(this, isNamedObject(), classOrObject.hasModifier(SEALED_KEYWORD), true, support) } private val tooComplex: Boolean by lazyPub { support.isTooComplexForUltraLightGeneration(classOrObject) } @@ -372,4 +372,4 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor } override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support) -} +} \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt index 2d9fccf9d0e..800e78d8781 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt @@ -35,6 +35,7 @@ internal class UltraLightMembersCreator( private val containingClass: KtLightClass, private val containingClassIsNamedObject: Boolean, private val containingClassIsSealed: Boolean, + private val mangleInternalFunctions: Boolean, private val support: KtUltraLightSupport ) { @@ -276,8 +277,9 @@ internal class UltraLightMembersCreator( val computedName = tryCompute(declaration, type) if (computedName !== null) return computedName - if (isInternalNonPublishedApi(declaration)) return KotlinTypeMapper.InternalNameMapper.mangleInternalName(name, support.moduleName) - return name + return if (mangleInternalFunctions && isInternalNonPublishedApi(declaration)) + KotlinTypeMapper.InternalNameMapper.mangleInternalName(name, support.moduleName) + else name } private tailrec fun isInternalNonPublishedApi(declaration: KtDeclaration): Boolean { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt index a024b89bace..2b3377d384d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDEKotlinAsJavaSupport.kt @@ -43,7 +43,7 @@ class IDEKotlinAsJavaSupport(private val project: Project) : KotlinAsJavaSupport KotlinFileFacadeClassByPackageIndex.getInstance() .get(packageFqName.asString(), project, scope) } - return facadeFilesInPackage.map { it.javaFileFacadeFqName.shortName().asString() } + return facadeFilesInPackage.map { it.javaFileFacadeFqName.shortName().asString() }.toSet() } override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection {