Fixed KT-7431 org.jetbrains.kotlin.idea.quickfix.AutoImportFix memory leak
#KT-7341 Fixed
This commit is contained in:
@@ -64,15 +64,10 @@ abstract class AutoImportFixBase<T: KtExpression>(expression: T, val diagnostics
|
|||||||
|
|
||||||
private val modificationCountOnCreate = PsiModificationTracker.SERVICE.getInstance(element.getProject()).getModificationCount()
|
private val modificationCountOnCreate = PsiModificationTracker.SERVICE.getInstance(element.getProject()).getModificationCount()
|
||||||
|
|
||||||
@Volatile private var anySuggestionFound: Boolean? = null
|
private val suggestionCount: Int by CachedValueProperty(
|
||||||
|
calculator = { computeSuggestions().size },
|
||||||
public val suggestions: Collection<DeclarationDescriptor> by CachedValueProperty(
|
timestampCalculator = { PsiModificationTracker.SERVICE.getInstance(element.project).modificationCount }
|
||||||
{
|
)
|
||||||
val descriptors = computeSuggestions()
|
|
||||||
anySuggestionFound = !descriptors.isEmpty()
|
|
||||||
descriptors
|
|
||||||
},
|
|
||||||
{ PsiModificationTracker.SERVICE.getInstance(element.getProject()).getModificationCount() })
|
|
||||||
|
|
||||||
protected abstract fun getSupportedErrors(): Collection<DiagnosticFactory<*>>
|
protected abstract fun getSupportedErrors(): Collection<DiagnosticFactory<*>>
|
||||||
protected abstract fun getCallTypeAndReceiver(): CallTypeAndReceiver<*, *>
|
protected abstract fun getCallTypeAndReceiver(): CallTypeAndReceiver<*, *>
|
||||||
@@ -83,11 +78,12 @@ abstract class AutoImportFixBase<T: KtExpression>(expression: T, val diagnostics
|
|||||||
|
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode() && HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) return false
|
if (ApplicationManager.getApplication().isUnitTestMode() && HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) return false
|
||||||
|
|
||||||
if (suggestions.isEmpty()) return false
|
if (suggestionCount == 0) return false
|
||||||
|
|
||||||
val addImportAction = createAction(element.project, editor)
|
val suggestions = computeSuggestions()
|
||||||
val hintText = ShowAutoImportPass.getMessage(suggestions.size > 1, addImportAction.highestPriorityFqName.asString())
|
val action = KotlinAddImportAction(element.project, editor, element, suggestions)
|
||||||
HintManager.getInstance().showQuestionHint(editor, hintText, element.getTextOffset(), element.getTextRange()!!.getEndOffset(), addImportAction)
|
val hintText = ShowAutoImportPass.getMessage(suggestions.size > 1, action.highestPriorityFqName.asString())
|
||||||
|
HintManager.getInstance().showQuestionHint(editor, hintText, element.textOffset, element.textRange.endOffset, action)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -97,11 +93,12 @@ abstract class AutoImportFixBase<T: KtExpression>(expression: T, val diagnostics
|
|||||||
override fun getFamilyName() = JetBundle.message("import.fix")
|
override fun getFamilyName() = JetBundle.message("import.fix")
|
||||||
|
|
||||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||||
= (super.isAvailable(project, editor, file)) && (anySuggestionFound ?: !suggestions.isEmpty())
|
= super.isAvailable(project, editor, file) && suggestionCount > 0
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||||
createAction(project, editor!!).execute()
|
val suggestions = computeSuggestions()
|
||||||
|
KotlinAddImportAction(project, editor!!, element, suggestions).execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +106,7 @@ abstract class AutoImportFixBase<T: KtExpression>(expression: T, val diagnostics
|
|||||||
|
|
||||||
private fun isOutdated() = modificationCountOnCreate != PsiModificationTracker.SERVICE.getInstance(element.getProject()).getModificationCount()
|
private fun isOutdated() = modificationCountOnCreate != PsiModificationTracker.SERVICE.getInstance(element.getProject()).getModificationCount()
|
||||||
|
|
||||||
protected open fun createAction(project: Project, editor: Editor) = KotlinAddImportAction(project, editor, element, suggestions)
|
fun computeSuggestions(): Collection<DeclarationDescriptor> {
|
||||||
|
|
||||||
protected fun computeSuggestions(): Collection<DeclarationDescriptor> {
|
|
||||||
if (!element.isValid()) return listOf()
|
if (!element.isValid()) return listOf()
|
||||||
if (element.getContainingFile() !is KtFile) return emptyList()
|
if (element.getContainingFile() !is KtFile) return emptyList()
|
||||||
|
|
||||||
@@ -127,7 +122,7 @@ abstract class AutoImportFixBase<T: KtExpression>(expression: T, val diagnostics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>):
|
fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>):
|
||||||
Collection<DeclarationDescriptor> {
|
Collection<DeclarationDescriptor> {
|
||||||
val nameStr = name.asString()
|
val nameStr = name.asString()
|
||||||
if (nameStr.isEmpty()) return emptyList()
|
if (nameStr.isEmpty()) return emptyList()
|
||||||
@@ -284,10 +279,6 @@ class MissingArrayAccessorAutoImportFix(element: KtArrayAccessExpression, diagno
|
|||||||
|
|
||||||
class MissingDelegateAccessorsAutoImportFix(element: KtExpression, diagnostics: Collection<Diagnostic>) :
|
class MissingDelegateAccessorsAutoImportFix(element: KtExpression, diagnostics: Collection<Diagnostic>) :
|
||||||
AutoImportFixBase<KtExpression>(element, diagnostics) {
|
AutoImportFixBase<KtExpression>(element, diagnostics) {
|
||||||
override fun createAction(project: Project, editor: Editor): KotlinAddImportAction {
|
|
||||||
return KotlinAddImportAction(project, editor, element, suggestions)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getImportNames(): Collection<Name> {
|
override fun getImportNames(): Collection<Name> {
|
||||||
return diagnostics.map {
|
return diagnostics.map {
|
||||||
val missingMethodSignature = Errors.DELEGATE_SPECIAL_FUNCTION_MISSING.cast(it).a
|
val missingMethodSignature = Errors.DELEGATE_SPECIAL_FUNCTION_MISSING.cast(it).a
|
||||||
@@ -314,8 +305,6 @@ class MissingDelegateAccessorsAutoImportFix(element: KtExpression, diagnostics:
|
|||||||
|
|
||||||
class MissingComponentsAutoImportFix(element: KtExpression, diagnostics: Collection<Diagnostic>) :
|
class MissingComponentsAutoImportFix(element: KtExpression, diagnostics: Collection<Diagnostic>) :
|
||||||
AutoImportFixBase<KtExpression>(element, diagnostics) {
|
AutoImportFixBase<KtExpression>(element, diagnostics) {
|
||||||
override fun createAction(project: Project, editor: Editor) = KotlinAddImportAction(project, editor, element, suggestions)
|
|
||||||
|
|
||||||
override fun getImportNames() = diagnostics.map { Name.identifier(Errors.COMPONENT_FUNCTION_MISSING.cast(it).a.identifier) }
|
override fun getImportNames() = diagnostics.map { Name.identifier(Errors.COMPONENT_FUNCTION_MISSING.cast(it).a.identifier) }
|
||||||
|
|
||||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.OPERATOR(element)
|
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.OPERATOR(element)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class KotlinReferenceImporter : ReferenceImporter {
|
|||||||
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
||||||
if (mainReference.resolveToDescriptors(bindingContext).isNotEmpty()) return false
|
if (mainReference.resolveToDescriptors(bindingContext).isNotEmpty()) return false
|
||||||
|
|
||||||
var suggestions = AutoImportFix(this).suggestions
|
var suggestions = AutoImportFix(this).computeSuggestions()
|
||||||
|
|
||||||
if (suggestions.distinctBy { it.importableFqName!! }.size() != 1) return false
|
if (suggestions.distinctBy { it.importableFqName!! }.size() != 1) return false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user