From 7a52cf103a8093225206ff7780a4aabc17dcf712 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 27 Jan 2020 18:50:20 +0300 Subject: [PATCH] Fix change signature refactoring Do not increase modification count for OutOfCodeBlockTracker when KtTypeCodeFragment is modified KtTypeCodeFragment is used in UI for providing completion for types. When OutOfCodeBlockModification happens it invalidates ModuleDescriptors But change signature relies on them which causes InvalidModuleException #KT-35903 fixed #KT-35689 fixed #KT-34415 fixed #KT-34415 fixed --- .../KotlinCodeBlockModificationListener.kt | 2 +- .../ui/KotlinChangeSignatureDialog.kt | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt index 9aa9dbfef93..f77b8e0f130 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/trackers/KotlinCodeBlockModificationListener.kt @@ -103,7 +103,7 @@ class KotlinCodeBlockModificationListener( if (inBlockElements.isEmpty()) { messageBusConnection.deliverImmediately() - if (physical && !isReplLine(ktFile.virtualFile)) { + if (physical && !isReplLine(ktFile.virtualFile) && ktFile !is KtTypeCodeFragment) { if (isLanguageTrackerEnabled) { kotlinOutOfCodeBlockTrackerImpl.incModificationCount() perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinChangeSignatureDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinChangeSignatureDialog.kt index 772a0856469..df401cceb79 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinChangeSignatureDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/ui/KotlinChangeSignatureDialog.kt @@ -332,7 +332,7 @@ class KotlinChangeSignatureDialog( override fun validateAndCommitData(): String? { if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite && - myReturnTypeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false).type == null + myReturnTypeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false, reanalyse = true).type == null ) { if (Messages.showOkCancelDialog( myProject, @@ -346,7 +346,7 @@ class KotlinChangeSignatureDialog( } for (item in parametersTableModel.items) { - if (item.typeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false).type == null) { + if (item.typeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false, reanalyse = true).type == null) { val paramText = if (item.parameter != parametersTableModel.receiver) "parameter '${item.parameter.name}'" else "receiver" if (Messages.showOkCancelDialog( myProject, @@ -455,10 +455,19 @@ class KotlinChangeSignatureDialog( return KotlinChangeSignatureProcessor(project, changeInfo, commandName) } - fun PsiCodeFragment?.getTypeInfo(isCovariant: Boolean, forPreview: Boolean): KotlinTypeInfo { + + private fun KtTypeCodeFragment.createCopy() = + KtPsiFactory(this).createTypeCodeFragment(text, this) + + fun PsiCodeFragment?.getTypeInfo(isCovariant: Boolean, forPreview: Boolean, reanalyse: Boolean = false): KotlinTypeInfo { if (this !is KtTypeCodeFragment) return KotlinTypeInfo(isCovariant) - val typeRef = getContentElement() + /* + As we do not update our caches on every KtTypeCodeFragment change + Caches are old and we cannot resolve type for old KtTypeCodeFragment + */ + val codeFragment = if (reanalyse) createCopy() else this + val typeRef = codeFragment.getContentElement() val type = typeRef?.analyze(BodyResolveMode.PARTIAL)?.get(BindingContext.TYPE, typeRef) return when { type != null && !type.isError -> KotlinTypeInfo(isCovariant, type, if (forPreview) typeRef.text else null)