Do not build light classes for local classes when the there is no class descriptor
These cases should be dealt with and this is only a way to degrade gracefully
This commit is contained in:
+13
-5
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.*
|
||||
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -172,7 +174,11 @@ public open class KtLightClassForExplicitDeclaration(
|
||||
}
|
||||
|
||||
private fun getLightClassData(): OutermostKotlinClassLightClassData {
|
||||
return getLightClassData(classOrObject)
|
||||
val lightClassData = getLightClassData(classOrObject)
|
||||
if (lightClassData !is OutermostKotlinClassLightClassData) {
|
||||
LOG.error("Invalid light class data for existing light class:\n$lightClassData\n${classOrObject.getElementTextWithContext()}")
|
||||
}
|
||||
return lightClassData as OutermostKotlinClassLightClassData
|
||||
}
|
||||
|
||||
private val _containingFile: PsiFile by lazy {
|
||||
@@ -380,7 +386,7 @@ public open class KtLightClassForExplicitDeclaration(
|
||||
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = classOrObject.stub
|
||||
|
||||
companion object {
|
||||
private val JAVA_API_STUB = Key.create<CachedValue<OutermostKotlinClassLightClassData>>("JAVA_API_STUB")
|
||||
private val JAVA_API_STUB = Key.create<CachedValue<WithFileStubAndExtraDiagnostics>>("JAVA_API_STUB")
|
||||
|
||||
private val jetTokenToPsiModifier = listOf(
|
||||
PUBLIC_KEYWORD to PsiModifier.PUBLIC,
|
||||
@@ -408,11 +414,11 @@ public open class KtLightClassForExplicitDeclaration(
|
||||
return if (internalName == null) null else JvmClassName.byInternalName(internalName).fqNameForClassNameWithoutDollars
|
||||
}
|
||||
|
||||
public fun getLightClassData(classOrObject: KtClassOrObject): OutermostKotlinClassLightClassData {
|
||||
public fun getLightClassData(classOrObject: KtClassOrObject): LightClassData {
|
||||
return getLightClassCachedValue(classOrObject).value
|
||||
}
|
||||
|
||||
public fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<OutermostKotlinClassLightClassData> {
|
||||
public fun getLightClassCachedValue(classOrObject: KtClassOrObject): CachedValue<WithFileStubAndExtraDiagnostics> {
|
||||
val outermostClassOrObject = getOutermostClassOrObject(classOrObject)
|
||||
var value = outermostClassOrObject.getUserData(JAVA_API_STUB)
|
||||
if (value == null) {
|
||||
@@ -424,7 +430,7 @@ public open class KtLightClassForExplicitDeclaration(
|
||||
}
|
||||
|
||||
private fun getLightClassDataExactly(classOrObject: KtClassOrObject): LightClassDataForKotlinClass? {
|
||||
val data = getLightClassData(classOrObject)
|
||||
val data = getLightClassData(classOrObject) as? OutermostKotlinClassLightClassData ?: return null
|
||||
return data.dataForClass(classOrObject)
|
||||
}
|
||||
|
||||
@@ -462,5 +468,7 @@ public open class KtLightClassForExplicitDeclaration(
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private val LOG = Logger.getInstance(KtLightClassForExplicitDeclaration::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,13 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
abstract val isLocal: Boolean
|
||||
|
||||
override fun compute(): CachedValueProvider.Result<T>? {
|
||||
return CachedValueProvider.Result.create(
|
||||
computeLightClassData(),
|
||||
if (isLocal) PsiModificationTracker.MODIFICATION_COUNT else PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||
)
|
||||
}
|
||||
|
||||
private fun computeLightClassData(): T {
|
||||
val packageFqName = packageFqName
|
||||
val files = files
|
||||
|
||||
@@ -110,6 +117,7 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
}
|
||||
|
||||
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub)
|
||||
return createLightClassData(javaFileStub, bindingContext, state.collectedExtraJvmDiagnostics)
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
@@ -118,11 +126,6 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
logErrorWithOSInfo(e, packageFqName, null)
|
||||
throw e
|
||||
}
|
||||
|
||||
return CachedValueProvider.Result.create(
|
||||
createLightClassData(javaFileStub, bindingContext, state.collectedExtraJvmDiagnostics),
|
||||
if (isLocal) PsiModificationTracker.MODIFICATION_COUNT else PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||
)
|
||||
}
|
||||
|
||||
private fun createJavaFileStub(packageFqName: FqName, files: Collection<KtFile>): PsiJavaFileStub {
|
||||
@@ -167,7 +170,7 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
||||
}
|
||||
|
||||
class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassOrObject) :
|
||||
LightClassDataProvider<OutermostKotlinClassLightClassData>(classOrObject.project) {
|
||||
LightClassDataProvider<WithFileStubAndExtraDiagnostics>(classOrObject.project) {
|
||||
|
||||
private val file: KtFile
|
||||
get() = classOrObject.getContainingKtFile()
|
||||
@@ -181,10 +184,8 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
|
||||
override fun createLightClassData(
|
||||
javaFileStub: PsiJavaFileStub,
|
||||
bindingContext: BindingContext,
|
||||
extraDiagnostics: Diagnostics): OutermostKotlinClassLightClassData {
|
||||
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject) ?: return OutermostKotlinClassLightClassData(
|
||||
javaFileStub, extraDiagnostics, FqName.ROOT, classOrObject,
|
||||
emptyMap<KtClassOrObject, InnerKotlinClassLightClassData>())
|
||||
extraDiagnostics: Diagnostics): WithFileStubAndExtraDiagnostics {
|
||||
val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassData
|
||||
|
||||
val fqName = predictClassFqName(bindingContext, classDescriptor)
|
||||
val allInnerClasses = CodegenBinding.getAllInnerClasses(bindingContext, classDescriptor)
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
|
||||
interface LightClassData
|
||||
|
||||
interface WithFileStubAndExtraDiagnostics {
|
||||
interface WithFileStubAndExtraDiagnostics: LightClassData {
|
||||
val javaFileStub: PsiJavaFileStub
|
||||
val extraDiagnostics: Diagnostics
|
||||
}
|
||||
@@ -33,6 +33,19 @@ interface LightClassDataForKotlinClass: LightClassData {
|
||||
val jvmQualifiedName: FqName
|
||||
}
|
||||
|
||||
object InvalidLightClassData: WithFileStubAndExtraDiagnostics, LightClassDataForKotlinClass {
|
||||
override val javaFileStub: PsiJavaFileStub
|
||||
get() = shouldNotBeCalled()
|
||||
override val extraDiagnostics: Diagnostics
|
||||
get() = shouldNotBeCalled()
|
||||
override val classOrObject: KtClassOrObject
|
||||
get() = shouldNotBeCalled()
|
||||
override val jvmQualifiedName: FqName
|
||||
get() = shouldNotBeCalled()
|
||||
|
||||
private fun shouldNotBeCalled(): Nothing = throw UnsupportedOperationException("Should not be called")
|
||||
}
|
||||
|
||||
data class KotlinFacadeLightClassData(
|
||||
override val javaFileStub: PsiJavaFileStub,
|
||||
override val extraDiagnostics: Diagnostics
|
||||
|
||||
@@ -39,7 +39,7 @@ public fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Dia
|
||||
}
|
||||
|
||||
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
|
||||
return KtLightClassForExplicitDeclaration.getLightClassData(ktClassOrObject).extraDiagnostics
|
||||
return (KtLightClassForExplicitDeclaration.getLightClassData(ktClassOrObject) as? OutermostKotlinClassLightClassData)?.extraDiagnostics ?: Diagnostics.EMPTY
|
||||
}
|
||||
|
||||
fun doGetDiagnostics(): Diagnostics? {
|
||||
|
||||
Reference in New Issue
Block a user