Disable to mangling facade functions + refactoring

This commit is contained in:
Igor Yakovlev
2019-05-27 17:09:19 +03:00
parent ac85849721
commit 8707edfaa3
6 changed files with 102 additions and 55 deletions
@@ -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<StubCacheKey, ValueWrapper>(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
}
}
@@ -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<LightClassDataHolder.ForFacade>,
myLightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>
) : KtLazyLightClass(manager) {
@Volatile
@VisibleForTesting
var isClsDelegateLoaded = false
override val clsDelegate: PsiClass
get() {
isClsDelegateLoaded = true
return super.clsDelegate
}
protected open val lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade> = myLightClassDataCache
get() {
isClsDelegateLoaded = true
return field
}
val files: Collection<KtFile> = 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(
@@ -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<LightClassDataHolder.ForFacade>,
files: Collection<KtFile>,
private val filesToSupports: Collection<Pair<KtFile, KtUltraLightSupport>>
private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>>
) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files) {
private inline fun <T> 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<KtLightMethod>
) {
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<KtLightMethod> by lazyPub {
val result = arrayListOf<KtLightMethod>()
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<KtLightMethod>().also { result ->
for ((file, support, creator) in filesWithSupportsWithCreators) {
loadMethodsFromFile(file, support, creator, result)
}
}
result
}
private val ownFieldsForNotTooComplex: List<KtLightField> by lazyPub {
hashSetOf<String>().let { nameCache ->
filesToSupportsToMemberCreators.flatMap { (file, _, creator) ->
filesWithSupportsWithCreators.flatMap { (file, _, creator) ->
file.declarations.filterIsInstance<KtProperty>().mapNotNull {
creator.createPropertyField(it, nameCache, forceStatic = true)
}
@@ -89,5 +111,5 @@ class KtUltraLightClassForFacade(
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
override fun copy(): KtLightClassForFacade =
KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesToSupports)
KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files, filesWithSupports)
}
@@ -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)
}
}
@@ -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 {
@@ -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<PsiClass> {