Avoid to call delegate from isInheritorDeep in UL-class
(plus small refacrotoring)
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -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
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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() =
|
||||||
|
|||||||
Reference in New Issue
Block a user