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 742dafe756b..8d9f31506c1 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 @@ -7,20 +7,15 @@ package org.jetbrains.kotlin.asJava.classes import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project -import com.intellij.openapi.util.registry.Registry -import com.intellij.psi.PsiManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import com.intellij.util.containers.SLRUCache -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade import org.jetbrains.kotlin.name.FqName -private data class StubCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope) +private data class FacadeCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope) private data class ValueWrapper(val value: KtLightClassForFacade?) { companion object { @@ -30,8 +25,8 @@ 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 cache = object : SLRUCache(20, 30) { + override fun createValue(key: FacadeCacheKey): ValueWrapper = KtLightClassForFacade.createForFacadeNoCache(key.fqName, key.searchScope, project) ?.let { ValueWrapper(it) } ?: ValueWrapper.Null @@ -39,12 +34,12 @@ class FacadeCache(private val project: Project) { } private val cachedValue: CachedValue = CachedValuesManager.getManager(project).createCachedValue( - { CachedValueProvider.Result.create(FacadeCacheData(), PsiModificationTracker.MODIFICATION_COUNT) }, false + { CachedValueProvider.Result.create(FacadeCacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) }, false ) operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? { synchronized(cachedValue) { - return cachedValue.value.cache.get(StubCacheKey(qualifiedName, searchScope)).value + return cachedValue.value.cache.get(FacadeCacheKey(qualifiedName, searchScope)).value } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt index 1c2e98458ee..04e11baf739 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt @@ -174,7 +174,7 @@ abstract class KtLightClassForSourceDeclaration( private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() } - open protected fun buildTypeParameterList() = LightClassUtil.buildLightTypeParameterList(this, classOrObject) + protected open fun buildTypeParameterList() = LightClassUtil.buildLightTypeParameterList(this, classOrObject) override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList @@ -459,10 +459,8 @@ fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() = !isAnnotationType && !isInterface && kotlinOrigin.annotationEntries.isNotEmpty() fun getOutermostClassOrObject(classOrObject: KtClassOrObject): KtClassOrObject { - val outermostClass = KtPsiUtil.getOutermostClassOrObject(classOrObject) + return KtPsiUtil.getOutermostClassOrObject(classOrObject) ?: throw IllegalStateException("Attempt to build a light class for a local class: " + classOrObject.text) - - return outermostClass } interface LightClassInheritanceHelper { 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 bec56e167ca..144065ee702 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.asJava.classes import com.google.common.annotations.VisibleForTesting import com.intellij.psi.* +import com.intellij.psi.impl.InheritanceImplUtil import com.intellij.psi.impl.PsiClassImplUtil import com.intellij.psi.impl.PsiSuperMethodImplUtil import com.intellij.psi.impl.light.LightMethodBuilder @@ -40,11 +41,19 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor KtLightClassImpl(classOrObject) { private val membersBuilder by lazyPub { - UltraLightMembersCreator(this, isNamedObject(), classOrObject.hasModifier(SEALED_KEYWORD), true, support) + UltraLightMembersCreator( + this, + isNamedObject(), + classOrObject.hasModifier(SEALED_KEYWORD), + mangleInternalFunctions = true, + support = support + ) } private val tooComplex: Boolean by lazyPub { support.isTooComplexForUltraLightGeneration(classOrObject) } + private val _deprecated by lazyPub { classOrObject.isDeprecated(support) } + override fun isFinal(isFinalByPsi: Boolean) = if (tooComplex) super.isFinal(isFinalByPsi) else isFinalByPsi @Volatile @@ -205,13 +214,17 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor for (declaration in this.classOrObject.declarations.filterNot { it.isHiddenByDeprecation(support) }) { if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue when (declaration) { - is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, false)) - is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, false, false)) + is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, forceStatic = false)) + is KtProperty -> result.addAll( + membersBuilder.propertyAccessors(declaration, declaration.isVar, forceStatic = false, onlyJvmStatic = false) + ) } } for (parameter in propertyParameters()) { - result.addAll(membersBuilder.propertyAccessors(parameter, parameter.isMutable, false, false)) + result.addAll( + membersBuilder.propertyAccessors(parameter, parameter.isMutable, forceStatic = false, onlyJvmStatic = false) + ) } if (!isInterface) { @@ -366,12 +379,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor override fun getScope(): PsiElement? = if (tooComplex) super.getScope() else parent - override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean { - //TODO: Implement inheritor deep to avoid access to clsDelegate - return super.isInheritorDeep(baseClass, classToByPass) - } - - private val _deprecated by lazyPub { classOrObject.isDeprecated(support) } + override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = + baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false override fun isDeprecated(): Boolean = _deprecated diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 74979ac3a16..3d5daea9aa2 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -67,7 +67,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG private inner class KtUltraLightSupportImpl(private val element: KtElement, private val module: Module) : KtUltraLightSupport { - fun KtDeclaration.forLogString(): String? = when (this) { + private fun KtDeclaration.forLogString(): String? = when (this) { is KtClassOrObject -> this.fqName?.asString() is KtFile -> this.packageFqNameByTree.asString() else -> this.text diff --git a/idea/tests/org/jetbrains/kotlin/idea/perf/UltraLightChecker.kt b/idea/tests/org/jetbrains/kotlin/idea/perf/UltraLightChecker.kt index 266991aad1b..0d0ab504c96 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/perf/UltraLightChecker.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/perf/UltraLightChecker.kt @@ -51,19 +51,8 @@ object UltraLightChecker { val ultraLightClass = KtLightClassForFacade.createForFacadeNoCache(fqName, searchScope, project) ?: return null KtUltraLightSupport.forceUsingOldLightClasses = oldForceFlag - if (gold != null) { - Assert.assertFalse(gold.javaClass.name.contains("Ultra")) - } + checkClassEquivalenceByRendering(gold, ultraLightClass) - val goldText = gold?.renderClass().orEmpty() - val ultraText = ultraLightClass.renderClass() - - if (goldText != ultraText) { - Assert.assertEquals( - "// Classic implementation:\n$goldText", - "// Ultra-light implementation:\n$ultraText" - ) - } return ultraLightClass } @@ -71,6 +60,12 @@ object UltraLightChecker { val gold = KtLightClassForSourceDeclaration.createNoCache(ktClass, forceUsingOldLightClasses = true) val ultraLightClass = LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass) ?: return null + checkClassEquivalenceByRendering(gold, ultraLightClass) + + return ultraLightClass + } + + private fun checkClassEquivalenceByRendering(gold: PsiClass?, ultraLightClass: PsiClass) { if (gold != null) { Assert.assertFalse(gold.javaClass.name.contains("Ultra")) } @@ -84,7 +79,6 @@ object UltraLightChecker { "// Ultra-light implementation:\n$ultraText" ) } - return ultraLightClass } private fun PsiAnnotation.renderAnnotation() =