Add text functions to KtLightClassForFacade

This commit is contained in:
Igor Yakovlev
2019-05-22 21:52:56 +03:00
parent 852a4bc0ca
commit 86e9018f49
8 changed files with 56 additions and 38 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.LightClassBuilder
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
@@ -45,7 +46,7 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
override fun createUltraLightClassForFacade(
facadeClassFqName: FqName,
searchScope: GlobalSearchScope,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
facadeFile: KtFile
): KtUltraLightClassForFacade? = null
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.asJava
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
@@ -50,7 +51,7 @@ abstract class LightClassGenerationSupport {
abstract fun createUltraLightClassForFacade(
facadeClassFqName: FqName,
searchScope: GlobalSearchScope,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
facadeFile: KtFile
): KtUltraLightClassForFacade?
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.components.ServiceManager
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
@@ -27,7 +28,7 @@ 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.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
import com.intellij.util.containers.SLRUCache
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
@@ -62,13 +63,13 @@ open class KtLightClassForFacade protected constructor(
override fun createValue(key: StubCacheKey): CachedValue<LightClassDataHolder.ForFacade> {
val stubProvider = LightClassDataProviderForFileFacade.ByProjectSource(project, key.fqName, key.searchScope)
return CachedValuesManager.getManager(project)
.createCachedValue<LightClassDataHolder.ForFacade>(stubProvider, /*trackValue = */false)
.createCachedValue<LightClassDataHolder.ForFacade>(stubProvider, false)
}
}
}
private val cachedValue: CachedValue<FacadeCacheData> = CachedValuesManager.getManager(project).createCachedValue<FacadeCacheData>(
{ CachedValueProvider.Result.create(FacadeCacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) }, false
{ CachedValueProvider.Result.create(FacadeCacheData(), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) }, false
)
operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): CachedValue<LightClassDataHolder.ForFacade> {
@@ -86,6 +87,8 @@ open class KtLightClassForFacade protected constructor(
val files: Collection<KtFile> = files.toSet() // needed for hashCode
private val firstFileInFacade by lazyPub { files.iterator().next() }
private val hashCode: Int =
computeHashCode()
@@ -199,7 +202,7 @@ open class KtLightClassForFacade protected constructor(
override val lightClassData
get() = lightClassDataCache.value.findDataForFacade(facadeClassFqName)
override fun getNavigationElement() = files.iterator().next()
override fun getNavigationElement() = firstFileInFacade
override fun isEquivalentTo(another: PsiElement?): Boolean {
return another is KtLightClassForFacade && Comparing.equal(another.qualifiedName, qualifiedName)
@@ -251,6 +254,7 @@ open class KtLightClassForFacade protected constructor(
override fun toString() = "${KtLightClassForFacade::class.java.simpleName}:$facadeClassFqName"
companion object {
fun createForFacade(
manager: PsiManager,
facadeClassFqName: FqName,
@@ -264,8 +268,17 @@ open class KtLightClassForFacade protected constructor(
if (ultraLightEnabled && files.count() == 1) {
val facadeFile = files.first()
LightClassGenerationSupport.getInstance(facadeFile.project)
.createUltraLightClassForFacade(facadeClassFqName, searchScope, facadeFile)?.let { return it }
return CachedValuesManager.getCachedValue(facadeFile) {
val lightClassDataCache = FacadeStubCache.getInstance(manager.project).get(facadeClassFqName, searchScope)
val classForFacade = LightClassGenerationSupport.getInstance(facadeFile.project)
.createUltraLightClassForFacade(facadeClassFqName, lightClassDataCache, facadeFile)
?: KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files)
CachedValueProvider.Result.create(classForFacade, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)
}
}
val lightClassDataCache = FacadeStubCache.getInstance(manager.project).get(facadeClassFqName, searchScope)
@@ -287,4 +300,14 @@ open class KtLightClassForFacade protected constructor(
override val originKind: LightClassOriginKind
get() = LightClassOriginKind.SOURCE
override fun getText() = firstFileInFacade.text ?: ""
override fun getTextRange(): TextRange = firstFileInFacade.textRange ?: TextRange.EMPTY_RANGE
override fun getTextOffset() = firstFileInFacade.textOffset
override fun getStartOffsetInParent() = firstFileInFacade.startOffsetInParent
override fun isWritable() = firstFileInFacade.isWritable
}
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.*
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.elements.KtLightField
@@ -26,7 +24,7 @@ class KtUltraLightClassForFacade(
private val support: KtUltraLightSupport
) : KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, listOf(file)) {
private val methodsBuilder by lazyPub { UltraLightMembersCreator(this, false, true, support) }
private val membersBuilder by lazyPub { UltraLightMembersCreator(this, false, true, support) }
private inline fun <T> forTooComplex(getter: () -> T): T {
check(tooComplex) {
@@ -50,8 +48,8 @@ class KtUltraLightClassForFacade(
for (declaration in file.declarations.filterNot { it.isHiddenByDeprecation(support) }) {
if (declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
when (declaration) {
is KtNamedFunction -> result.addAll(methodsBuilder.createMethods(declaration, true))
is KtProperty -> result.addAll(methodsBuilder.propertyAccessors(declaration, declaration.isVar, true, false))
is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, true))
is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, true, false))
}
}
@@ -61,7 +59,7 @@ class KtUltraLightClassForFacade(
private val ownFieldsForNotTooComplex: List<KtLightField> by lazyPub {
hashSetOf<String>().run {
file.declarations.filterIsInstance<KtProperty>().mapNotNull {
methodsBuilder.createPropertyField(it, this, forceStatic = true)
membersBuilder.createPropertyField(it, this, forceStatic = true)
}
}
}
@@ -70,13 +68,8 @@ class KtUltraLightClassForFacade(
override fun getOwnMethods() = if (!tooComplex) ownMethodsForNotTooComplex else super.getOwnMethods()
override fun hashCode(): Int = file.hashCode()
override fun toString(): String = "UltraLight class for file facade"
override fun equals(other: Any?): Boolean = this === other
override fun copy(): KtLightClassForFacade = KtUltraLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, file, support)
override fun setName(name: String): PsiElement? = this
}
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val support: KtUltraLightSupport) :
KtLightClassImpl(classOrObject) {
private val methodsBuilder by lazyPub {
private val membersBuilder by lazyPub {
UltraLightMembersCreator(this, isNamedObject(), classOrObject.hasModifier(SEALED_KEYWORD), support)
}
@@ -128,14 +128,14 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
val usedNames = hashSetOf<String>()
for (parameter in propertyParameters()) {
methodsBuilder.createPropertyField(parameter, usedNames, forceStatic = false)?.let(result::add)
membersBuilder.createPropertyField(parameter, usedNames, forceStatic = false)?.let(result::add)
}
this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
result.add(
KtUltraLightField(
companion,
methodsBuilder.generateUniqueFieldName(companion.name.orEmpty(), usedNames),
membersBuilder.generateUniqueFieldName(companion.name.orEmpty(), usedNames),
this,
support,
setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC)
@@ -144,7 +144,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
for (property in companion.declarations.filterIsInstance<KtProperty>()) {
if (isInterface && !property.isConstOrJvmField()) continue
methodsBuilder.createPropertyField(property, usedNames, true)?.let(result::add)
membersBuilder.createPropertyField(property, usedNames, true)?.let(result::add)
}
}
@@ -156,7 +156,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
// Probably, the same should work for const vals but it doesn't at the moment (see KT-28294)
if (isCompanion && (containingClass?.isInterface == false || property.isJvmField())) continue
methodsBuilder.createPropertyField(property, usedNames, forceStatic = this.classOrObject is KtObjectDeclaration)?.let(result::add)
membersBuilder.createPropertyField(property, usedNames, forceStatic = this.classOrObject is KtObjectDeclaration)?.let(result::add)
}
}
@@ -200,13 +200,13 @@ 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(methodsBuilder.createMethods(declaration, false))
is KtProperty -> result.addAll(methodsBuilder.propertyAccessors(declaration, declaration.isVar, false,false))
is KtNamedFunction -> result.addAll(membersBuilder.createMethods(declaration, false))
is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, false, false))
}
}
for (parameter in propertyParameters()) {
result.addAll(methodsBuilder.propertyAccessors(parameter, parameter.isMutable, false,false))
result.addAll(membersBuilder.propertyAccessors(parameter, parameter.isMutable, false, false))
}
if (!isInterface) {
@@ -216,8 +216,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
this.classOrObject.companionObjects.firstOrNull()?.let { companion ->
for (declaration in companion.declarations.filterNot { isHiddenByDeprecation(it) }) {
when (declaration) {
is KtNamedFunction -> if (isJvmStatic(declaration)) result.addAll(methodsBuilder.createMethods(declaration, true))
is KtProperty -> result.addAll(methodsBuilder.propertyAccessors(declaration, declaration.isVar, false,true))
is KtNamedFunction -> if (isJvmStatic(declaration)) result.addAll(membersBuilder.createMethods(declaration, true))
is KtProperty -> result.addAll(membersBuilder.propertyAccessors(declaration, declaration.isVar, false, true))
}
}
}
@@ -298,7 +298,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
result.add(defaultConstructor())
}
for (constructor in constructors.filterNot { isHiddenByDeprecation(it) }) {
result.addAll(methodsBuilder.createMethods(constructor, false, forcePrivate = isEnum))
result.addAll(membersBuilder.createMethods(constructor, false, forcePrivate = isEnum))
}
val primary = classOrObject.primaryConstructor
if (primary != null && shouldGenerateNoArgOverload(primary)) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.*
import com.intellij.psi.impl.cache.ModifierFlags
import com.intellij.psi.impl.cache.TypeInfo
@@ -312,4 +313,4 @@ internal fun KtDeclaration.simpleVisibility(): String = when {
hasModifier(KtTokens.PRIVATE_KEYWORD) -> PsiModifier.PRIVATE
hasModifier(KtTokens.PROTECTED_KEYWORD) -> PsiModifier.PROTECTED
else -> PsiModifier.PUBLIC
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
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
@@ -178,13 +179,10 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun createUltraLightClassForFacade(
facadeClassFqName: FqName,
searchScope: GlobalSearchScope,
lightClassDataCache: CachedValue<LightClassDataHolder.ForFacade>,
facadeFile: KtFile
): KtUltraLightClassForFacade? {
val lightClassDataCache =
KtLightClassForFacade.FacadeStubCache.getInstance(project).get(facadeClassFqName, searchScope)
if (facadeFile.isScript()) return null
val module = ModuleUtilCore.findModuleForPsiElement(facadeFile) ?: return null
@@ -12,6 +12,7 @@ import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.KtUltraLightClass
import org.jetbrains.kotlin.asJava.classes.KtUltraLightSupport
import org.jetbrains.kotlin.asJava.classes.isPrivateOrParameterInPrivateMethod
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
@@ -20,9 +21,9 @@ import org.jetbrains.kotlin.psi.KtFile
import org.junit.Assert
fun UsefulTestCase.forceUsingOldLightClassesForTest() {
KtUltraLightClass.forceUsingOldLightClasses = true
KtUltraLightSupport.forceUsingOldLightClasses = true
Disposer.register(testRootDisposable, Disposable {
KtUltraLightClass.forceUsingOldLightClasses = false
KtUltraLightSupport.forceUsingOldLightClasses = false
})
}