[Invariant Fix] Avoid using invalid descriptors in RemovePartsFromPropertyFix

org.jetbrains.kotlin.descriptors.InvalidModuleException: Accessing invalid module descriptor <production sources for module light_idea_test_case> is a module[ModuleDescriptorImpl@89f9a78]
	at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.assertValid(ModuleDescriptorImpl.kt:51)
	at org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl.getPackage(ModuleDescriptorImpl.kt:70)
	at org.jetbrains.kotlin.descriptors.FindClassInModuleKt.findClassifierAcrossModuleDependencies(findClassInModule.kt:23)
	at org.jetbrains.kotlin.types.KotlinTypeKt.refineDescriptor(KotlinType.kt:185)
	at org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor$1$1.invoke(AbstractClassDescriptor.java:50)
	at org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor$1$1.invoke(AbstractClassDescriptor.java:47)
	at org.jetbrains.kotlin.types.SimpleTypeImpl.refine(KotlinTypeFactory.kt:210)
	at org.jetbrains.kotlin.types.SimpleTypeImpl.refine(KotlinTypeFactory.kt:182)
	at org.jetbrains.kotlin.types.AbstractTypeConstructor$ModuleViewTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:38)
	at org.jetbrains.kotlin.types.AbstractTypeConstructor$ModuleViewTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:33)
	at org.jetbrains.kotlin.types.TypeUtils.getImmediateSupertypes(TypeUtils.java:230)
	at org.jetbrains.kotlin.types.TypeUtils.collectAllSupertypes(TypeUtils.java:255)
	at org.jetbrains.kotlin.types.TypeUtils.getAllSupertypes(TypeUtils.java:268)
	at org.jetbrains.kotlin.idea.util.TypeUtils.getResolvableApproximations(TypeUtils.kt:128)
	at org.jetbrains.kotlin.idea.util.TypeUtils.getResolvableApproximations$default(TypeUtils.kt:126)
	at org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention$Companion$createTypeExpressionForTemplate$1.invoke(SpecifyTypeExplicitlyIntention.kt:133)
	at org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention$Companion.createTypeExpressionForTemplate(SpecifyTypeExplicitlyIntention.kt:149)
	at org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention$Companion.addTypeAnnotationWithTemplate(SpecifyTypeExplicitlyIntention.kt:234)
	at org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention$Companion.addTypeAnnotationWithTemplate$default(SpecifyTypeExplicitlyIntention.kt:229)
	at org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention$Companion.addTypeAnnotation(SpecifyTypeExplicitlyIntention.kt:195)
	at org.jetbrains.kotlin.idea.quickfix.RemovePartsFromPropertyFix.invoke(RemovePartsFromPropertyFix.kt:82)
	at org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction.invoke(KotlinQuickFixAction.kt:37)
	at com.intellij.codeInsight.intention.impl.IntentionActionWithTextCaching$MyIntentionAction.invoke(IntentionActionWithTextCaching.java:179)
	at com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler.lambda$invokeIntention$4(ShowIntentionActionsHandler.java

See QF tests like QuickFixTestGenerated$RemoveRedundantInitializer.testSimple
This commit is contained in:
Denis Zharkov
2019-05-24 17:29:10 +03:00
committed by Dmitry Savvinov
parent 5f10252185
commit d20516779a
@@ -21,12 +21,16 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.intentions.SpecifyTypeExplicitlyIntention
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.refinement.TypeRefinement
open class RemovePartsFromPropertyFix(
element: KtProperty,
@@ -79,6 +83,18 @@ open class RemovePartsFromPropertyFix(
}
val replaceElement = element?.replace(newElement) as? KtProperty
if (replaceElement != null && typeToAdd != null) {
// `refineType` call here is needed to avoid InvalidModuleException exception
//
// It happens because after refinement KotlinTypes may access ModuleDescriptor content
// and that module becomes invalid after replacement two lines above
//
// The actual problem is that we use a type obtained from the obsolete analysis session
// The ideal fix would be using a String that needs to be rendered instead of actual type
//
// But calling another type refinement also helps because it makes KotlinType instance using new module descriptor
@UseExperimental(TypeRefinement::class)
typeToAdd = replaceElement.getResolutionFacade().frontendService<KotlinTypeRefiner>().refineType(typeToAdd)
SpecifyTypeExplicitlyIntention.addTypeAnnotation(editor, replaceElement, typeToAdd)
}
}