Avoid to call delegate from isInheritorDeep in UL-class

(plus small refacrotoring)
This commit is contained in:
Igor Yakovlev
2019-05-29 17:26:01 +03:00
parent eaa36d4d27
commit db4ba238eb
5 changed files with 34 additions and 38 deletions
@@ -7,20 +7,15 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project 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.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache 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 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?) { private data class ValueWrapper(val value: KtLightClassForFacade?) {
companion object { companion object {
@@ -30,8 +25,8 @@ private data class ValueWrapper(val value: KtLightClassForFacade?) {
class FacadeCache(private val project: Project) { class FacadeCache(private val project: Project) {
private inner class FacadeCacheData { private inner class FacadeCacheData {
val cache = object : SLRUCache<StubCacheKey, ValueWrapper>(20, 30) { val cache = object : SLRUCache<FacadeCacheKey, ValueWrapper>(20, 30) {
override fun createValue(key: StubCacheKey): ValueWrapper = override fun createValue(key: FacadeCacheKey): ValueWrapper =
KtLightClassForFacade.createForFacadeNoCache(key.fqName, key.searchScope, project) KtLightClassForFacade.createForFacadeNoCache(key.fqName, key.searchScope, project)
?.let { ValueWrapper(it) } ?.let { ValueWrapper(it) }
?: ValueWrapper.Null ?: ValueWrapper.Null
@@ -39,12 +34,12 @@ class FacadeCache(private val project: Project) {
} }
private val cachedValue: CachedValue<FacadeCacheData> = CachedValuesManager.getManager(project).createCachedValue( private val cachedValue: CachedValue<FacadeCacheData> = 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? { operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): KtLightClassForFacade? {
synchronized(cachedValue) { synchronized(cachedValue) {
return cachedValue.value.cache.get(StubCacheKey(qualifiedName, searchScope)).value return cachedValue.value.cache.get(FacadeCacheKey(qualifiedName, searchScope)).value
} }
} }
@@ -174,7 +174,7 @@ abstract class KtLightClassForSourceDeclaration(
private val _typeParameterList: PsiTypeParameterList by lazyPub { buildTypeParameterList() } 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 override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
@@ -459,10 +459,8 @@ fun KtLightClassForSourceDeclaration.isPossiblyAffectedByAllOpen() =
!isAnnotationType && !isInterface && kotlinOrigin.annotationEntries.isNotEmpty() !isAnnotationType && !isInterface && kotlinOrigin.annotationEntries.isNotEmpty()
fun getOutermostClassOrObject(classOrObject: KtClassOrObject): KtClassOrObject { 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) ?: throw IllegalStateException("Attempt to build a light class for a local class: " + classOrObject.text)
return outermostClass
} }
interface LightClassInheritanceHelper { interface LightClassInheritanceHelper {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.asJava.classes
import com.google.common.annotations.VisibleForTesting import com.google.common.annotations.VisibleForTesting
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.InheritanceImplUtil
import com.intellij.psi.impl.PsiClassImplUtil import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.impl.PsiSuperMethodImplUtil import com.intellij.psi.impl.PsiSuperMethodImplUtil
import com.intellij.psi.impl.light.LightMethodBuilder import com.intellij.psi.impl.light.LightMethodBuilder
@@ -40,11 +41,19 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
KtLightClassImpl(classOrObject) { KtLightClassImpl(classOrObject) {
private val membersBuilder by lazyPub { 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 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 override fun isFinal(isFinalByPsi: Boolean) = if (tooComplex) super.isFinal(isFinalByPsi) else isFinalByPsi
@Volatile @Volatile
@@ -205,13 +214,17 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
for (declaration in this.classOrObject.declarations.filterNot { it.isHiddenByDeprecation(support) }) { for (declaration in this.classOrObject.declarations.filterNot { it.isHiddenByDeprecation(support) }) {
if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue if (declaration.hasModifier(PRIVATE_KEYWORD) && isInterface) continue
when (declaration) { when (declaration) {
is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, false)) is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, forceStatic = false))
is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, false, false)) is KtProperty -> result.addAll(
membersBuilder.propertyAccessors(declaration, declaration.isVar, forceStatic = false, onlyJvmStatic = false)
)
} }
} }
for (parameter in propertyParameters()) { 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) { 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 getScope(): PsiElement? = if (tooComplex) super.getScope() else parent
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean { override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
//TODO: Implement inheritor deep to avoid access to clsDelegate baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false
return super.isInheritorDeep(baseClass, classToByPass)
}
private val _deprecated by lazyPub { classOrObject.isDeprecated(support) }
override fun isDeprecated(): Boolean = _deprecated override fun isDeprecated(): Boolean = _deprecated
@@ -67,7 +67,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
private inner class KtUltraLightSupportImpl(private val element: KtElement, private val module: Module) : KtUltraLightSupport { 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 KtClassOrObject -> this.fqName?.asString()
is KtFile -> this.packageFqNameByTree.asString() is KtFile -> this.packageFqNameByTree.asString()
else -> this.text else -> this.text
@@ -51,19 +51,8 @@ object UltraLightChecker {
val ultraLightClass = KtLightClassForFacade.createForFacadeNoCache(fqName, searchScope, project) ?: return null val ultraLightClass = KtLightClassForFacade.createForFacadeNoCache(fqName, searchScope, project) ?: return null
KtUltraLightSupport.forceUsingOldLightClasses = oldForceFlag KtUltraLightSupport.forceUsingOldLightClasses = oldForceFlag
if (gold != null) { checkClassEquivalenceByRendering(gold, ultraLightClass)
Assert.assertFalse(gold.javaClass.name.contains("Ultra"))
}
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 return ultraLightClass
} }
@@ -71,6 +60,12 @@ object UltraLightChecker {
val gold = KtLightClassForSourceDeclaration.createNoCache(ktClass, forceUsingOldLightClasses = true) val gold = KtLightClassForSourceDeclaration.createNoCache(ktClass, forceUsingOldLightClasses = true)
val ultraLightClass = LightClassGenerationSupport.getInstance(ktClass.project).createUltraLightClass(ktClass) ?: return null 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) { if (gold != null) {
Assert.assertFalse(gold.javaClass.name.contains("Ultra")) Assert.assertFalse(gold.javaClass.name.contains("Ultra"))
} }
@@ -84,7 +79,6 @@ object UltraLightChecker {
"// Ultra-light implementation:\n$ultraText" "// Ultra-light implementation:\n$ultraText"
) )
} }
return ultraLightClass
} }
private fun PsiAnnotation.renderAnnotation() = private fun PsiAnnotation.renderAnnotation() =