Do not build dummy light classes for serialization-related classes

Otherwise, whether LazyLightClassMemberMatchingError happens
or other type of errors because serialization plugin expects
full resolution in the correct module

Currently, only @Serializable annotation leads to exceptions,
but just in case we consider both of them as potentially problematic

 #KT-26895 Fixed
This commit is contained in:
Denis Zharkov
2018-09-17 16:25:40 +03:00
parent fe9ce45e1d
commit a4b2e5964a
3 changed files with 39 additions and 5 deletions
@@ -52,6 +52,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.annotations.KOTLINX_SERIALIZABLE_FQ_NAME
import org.jetbrains.kotlin.resolve.annotations.KOTLINX_SERIALIZER_FQ_NAME
import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
@@ -158,7 +160,10 @@ internal object IDELightClassContexts {
listOf(classOrObject.containingKtFile)
)
ForceResolveUtil.forceResolveAllContents(resolveSession.resolveToDescriptor(classOrObject))
val descriptor = resolveSession.resolveToDescriptor(classOrObject) as? ClassDescriptor ?: return null
if (!isDummyResolveApplicableByDescriptor(descriptor)) return null
ForceResolveUtil.forceResolveAllContents(descriptor)
return IDELightClassConstructionContext(resolveSession.bindingContext, resolveSession.moduleDescriptor, classOrObject.languageVersionSettings, LIGHT)
}
@@ -183,9 +188,30 @@ internal object IDELightClassContexts {
if (hasMembersOverridingInternalMembers(classOrObject)) return false
if (hasSerializationLikeAnnotations(classOrObject)) return false
return classOrObject.declarations.filterIsInstance<KtClassOrObject>().all { isDummyResolveApplicable(it) }
}
private fun hasSerializationLikeAnnotations(classOrObject: KtClassOrObject) =
classOrObject.annotationEntries.any { isSerializableOrSerializerShortName(it.shortName) }
private fun isDummyResolveApplicableByDescriptor(classDescriptor: ClassDescriptor): Boolean {
if (classDescriptor.annotations.any { isSerializableOrSerializerFqName(it.fqName) }) return false
return classDescriptor
.unsubstitutedInnerClassesScope
.getContributedDescriptors()
.filterIsInstance<ClassDescriptor>()
.all(::isDummyResolveApplicableByDescriptor)
}
private fun isSerializableOrSerializerShortName(shortName: Name?) =
shortName == KOTLINX_SERIALIZABLE_FQ_NAME.shortName() || shortName == KOTLINX_SERIALIZER_FQ_NAME.shortName()
private fun isSerializableOrSerializerFqName(fqName: FqName?) =
fqName == KOTLINX_SERIALIZABLE_FQ_NAME || fqName == KOTLINX_SERIALIZER_FQ_NAME
private fun hasDelegatedSupertypes(classOrObject: KtClassOrObject) =
classOrObject.superTypeListEntries.any { it is KtDelegatedSuperTypeEntry }
@@ -332,7 +358,9 @@ internal object IDELightClassContexts {
FqName("kotlin.PublishedApi") +
FqName("kotlin.Deprecated") +
FqName("kotlin.internal.InlineOnly") +
FqName("kotlinx.android.parcel.Parcelize")
FqName("kotlinx.android.parcel.Parcelize") +
KOTLINX_SERIALIZABLE_FQ_NAME +
KOTLINX_SERIALIZER_FQ_NAME
}
class AdHocAnnotationResolver(