Refactor LightClassData: remove redundant entities

This commit is contained in:
Pavel V. Talanov
2017-02-16 13:05:00 +03:00
parent 0a0e628068
commit 71161e218b
5 changed files with 34 additions and 54 deletions
@@ -17,43 +17,23 @@
package org.jetbrains.kotlin.asJava.builder
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
interface LightClassData
interface WithFileStubAndExtraDiagnostics: LightClassData {
interface LightClassData {
val javaFileStub: PsiJavaFileStub
val extraDiagnostics: Diagnostics
}
interface LightClassDataForKotlinClass: LightClassData {
val classOrObject: KtClassOrObject
}
object InvalidLightClassData: WithFileStubAndExtraDiagnostics, LightClassDataForKotlinClass {
object InvalidLightClassData: LightClassData {
override val javaFileStub: PsiJavaFileStub
get() = shouldNotBeCalled()
override val extraDiagnostics: Diagnostics
get() = shouldNotBeCalled()
override val classOrObject: KtClassOrObject
get() = shouldNotBeCalled()
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
}
data class KotlinFacadeLightClassData(
data class LightClassDataImpl(
override val javaFileStub: PsiJavaFileStub,
override val extraDiagnostics: Diagnostics
): LightClassData, WithFileStubAndExtraDiagnostics
data class InnerKotlinClassLightClassData(
override val classOrObject: KtClassOrObject
): LightClassDataForKotlinClass
data class OutermostKotlinClassLightClassData(
override val javaFileStub: PsiJavaFileStub,
override val extraDiagnostics: Diagnostics,
override val classOrObject: KtClassOrObject
): LightClassDataForKotlinClass, WithFileStubAndExtraDiagnostics
): LightClassData
@@ -51,7 +51,7 @@ import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
abstract class LightClassDataProvider<T : LightClassData>(
private val project: Project
) : CachedValueProvider<T> {
@@ -161,7 +161,7 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
}
class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassOrObject) :
LightClassDataProvider<WithFileStubAndExtraDiagnostics>(classOrObject.project) {
LightClassDataProvider<LightClassData>(classOrObject.project) {
private val file: KtFile
get() = classOrObject.containingKtFile
@@ -175,14 +175,14 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
override fun createLightClassData(
javaFileStub: PsiJavaFileStub,
bindingContext: BindingContext,
extraDiagnostics: Diagnostics): WithFileStubAndExtraDiagnostics {
extraDiagnostics: Diagnostics): LightClassData {
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassData
return OutermostKotlinClassLightClassData(
return LightClassDataImpl(
javaFileStub,
extraDiagnostics,
classOrObject)
extraDiagnostics
)
}
override val files: Collection<KtFile>
@@ -258,7 +258,7 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
sealed class LightClassDataProviderForFileFacade private constructor(
protected val project: Project, protected val facadeFqName: FqName
) : LightClassDataProvider<KotlinFacadeLightClassData>(project) {
) : LightClassDataProvider<LightClassDataImpl>(project) {
override val packageFqName: FqName
get() = facadeFqName.parent()
@@ -271,8 +271,9 @@ sealed class LightClassDataProviderForFileFacade private constructor(
override fun createLightClassData(
javaFileStub: PsiJavaFileStub,
bindingContext: BindingContext,
extraDiagnostics: Diagnostics): KotlinFacadeLightClassData {
return KotlinFacadeLightClassData(javaFileStub, extraDiagnostics)
extraDiagnostics: Diagnostics
): LightClassDataImpl {
return LightClassDataImpl(javaFileStub, extraDiagnostics)
}
override val generateClassFilter: GenerationState.GenerateClassFilter
@@ -31,7 +31,7 @@ import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.builder.KotlinFacadeLightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataImpl
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
@@ -51,17 +51,17 @@ import javax.swing.Icon
class KtLightClassForFacade private constructor(
manager: PsiManager,
private val facadeClassFqName: FqName,
private val lightClassDataCache: CachedValue<KotlinFacadeLightClassData>,
private val lightClassDataCache: CachedValue<LightClassDataImpl>,
files: Collection<KtFile>
) : KtLightClassBase(manager) {
private data class StubCacheKey(val fqName: FqName, val searchScope: GlobalSearchScope)
class FacadeStubCache(private val project: Project) {
private inner class FacadeCacheData {
val cache = object : SLRUCache<StubCacheKey, CachedValue<KotlinFacadeLightClassData>>(20, 30) {
override fun createValue(key: StubCacheKey): CachedValue<KotlinFacadeLightClassData> {
val cache = object : SLRUCache<StubCacheKey, CachedValue<LightClassDataImpl>>(20, 30) {
override fun createValue(key: StubCacheKey): CachedValue<LightClassDataImpl> {
val stubProvider = LightClassDataProviderForFileFacade.ByProjectSource(project, key.fqName, key.searchScope)
return CachedValuesManager.getManager(project).createCachedValue<KotlinFacadeLightClassData>(stubProvider, /*trackValue = */false)
return CachedValuesManager.getManager(project).createCachedValue<LightClassDataImpl>(stubProvider, /*trackValue = */false)
}
}
}
@@ -70,7 +70,7 @@ class KtLightClassForFacade private constructor(
{ CachedValueProvider.Result.create(FacadeCacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) },
/*trackValue = */ false)
operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): CachedValue<KotlinFacadeLightClassData> {
operator fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): CachedValue<LightClassDataImpl> {
synchronized (cachedValue) {
return cachedValue.value.cache.get(StubCacheKey(qualifiedName, searchScope))
}
@@ -284,7 +284,7 @@ class KtLightClassForFacade private constructor(
): KtLightClassForFacade {
// TODO: refactor, using cached value doesn't make sense for this case
val cachedValue = CachedValuesManager.getManager(manager.project).
createCachedValue<KotlinFacadeLightClassData>(
createCachedValue<LightClassDataImpl>(
LightClassDataProviderForFileFacade.ByFile(manager.project, facadeClassFqName, file), /*trackValue = */false
)
return KtLightClassForFacade(manager, facadeClassFqName, cachedValue, listOf(file))
@@ -36,9 +36,8 @@ import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.getOriginalElement
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataImpl
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForClassOrObject
import org.jetbrains.kotlin.asJava.builder.OutermostKotlinClassLightClassData
import org.jetbrains.kotlin.asJava.builder.WithFileStubAndExtraDiagnostics
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.asJava.elements.KtLightModifierListWithExplicitModifiers
@@ -61,7 +60,7 @@ import java.util.*
import javax.swing.Icon
abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtClassOrObject)
: KtLightClassBase(classOrObject.manager), StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
: KtLightClassBase(classOrObject.manager), StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
private val lightIdentifier = KtLightIdentifier(this, classOrObject)
private val _extendsList by lazy(LazyThreadSafetyMode.PUBLICATION) {
@@ -109,12 +108,12 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
return LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor
}
private fun getLightClassData(): OutermostKotlinClassLightClassData {
private fun getLightClassData(): LightClassDataImpl {
val lightClassData = getLightClassData(classOrObject)
if (lightClassData !is OutermostKotlinClassLightClassData) {
if (lightClassData !is LightClassDataImpl) {
LOG.error("Invalid light class data for existing light class:\n$lightClassData\n${classOrObject.getElementTextWithContext()}")
}
return lightClassData as OutermostKotlinClassLightClassData
return lightClassData as LightClassDataImpl
}
private val _containingFile: PsiFile by lazy(LazyThreadSafetyMode.PUBLICATION) {
@@ -194,7 +193,7 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
override fun getName(): String? = classOrObject.nameAsName?.asString()
private val _modifierList : PsiModifierList by lazy(LazyThreadSafetyMode.PUBLICATION) {
private val _modifierList: PsiModifierList by lazy(LazyThreadSafetyMode.PUBLICATION) {
object : KtLightModifierListWithExplicitModifiers(this@KtLightClassForSourceDeclaration, computeModifiers()) {
override val delegate: PsiAnnotationOwner
get() = this@KtLightClassForSourceDeclaration.delegate.modifierList!!
@@ -342,17 +341,17 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
override fun getImplementsList() = _implementsList
companion object {
private val JAVA_API_STUB = Key.create<CachedValue<WithFileStubAndExtraDiagnostics>>("JAVA_API_STUB")
private val JAVA_API_STUB = Key.create<CachedValue<LightClassData>>("JAVA_API_STUB")
private val jetTokenToPsiModifier = listOf(
PUBLIC_KEYWORD to PsiModifier.PUBLIC,
INTERNAL_KEYWORD to PsiModifier.PUBLIC,
INTERNAL_KEYWORD to PsiModifier.PUBLIC,
PROTECTED_KEYWORD to PsiModifier.PROTECTED,
FINAL_KEYWORD to PsiModifier.FINAL)
fun create(classOrObject: KtClassOrObject): KtLightClassForSourceDeclaration? {
if (classOrObject.containingKtFile.isScript || classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
if (classOrObject.containingKtFile.isScript || classOrObject.hasModifier(KtTokens.HEADER_KEYWORD)) {
return null
}
@@ -387,10 +386,10 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
return getLightClassCachedValue(classOrObject).value
}
fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<WithFileStubAndExtraDiagnostics> {
fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<LightClassData> {
var value =
getOutermostClassOrObject(classOrObject).getUserData(JAVA_API_STUB) // stub computed for outer class can be used for inner/nested
?: classOrObject.getUserData (JAVA_API_STUB)
?: classOrObject.getUserData(JAVA_API_STUB)
if (value == null) {
value = CachedValuesManager.getManager(classOrObject.project).createCachedValue(
LightClassDataProviderForClassOrObject(classOrObject), false)
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.asJava
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.builder.OutermostKotlinClassLightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataImpl
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.diagnostics.Diagnostic
@@ -42,7 +42,7 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
}
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
return (KtLightClassForSourceDeclaration.getLightClassData(ktClassOrObject) as? OutermostKotlinClassLightClassData)?.extraDiagnostics ?: Diagnostics.EMPTY
return (KtLightClassForSourceDeclaration.getLightClassData(ktClassOrObject) as? LightClassDataImpl)?.extraDiagnostics ?: Diagnostics.EMPTY
}
fun doGetDiagnostics(): Diagnostics? {