From bdb86162aa7a869398f7df1fe63ceba7bd1b86fe Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 15 Jan 2018 19:57:43 +0300 Subject: [PATCH] keep ParameterInfoHandler instances stateless move state from MethodParameterInfoHandler to controller (ParameterInfoController) --- .../api/impls/MethodParameterInfoHandler.java | 46 ++++++++++--------- .../DeleteParameterInfoContext.java | 10 ++++ .../parameterInfo/ParameterInfoHandler.java | 2 +- .../UpdateParameterInfoContext.java | 3 ++ .../hint/ParameterInfoController.java | 26 +++++++---- .../MockUpdateParameterInfoContext.java | 6 +++ .../jetbrains/python/PyParameterInfoTest.java | 6 +++ 7 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/lang/parameterInfo/DeleteParameterInfoContext.java diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java index 1fef9a39dbbd..da56529c9495 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/api/impls/MethodParameterInfoHandler.java @@ -23,7 +23,9 @@ import com.intellij.openapi.editor.Inlay; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -53,12 +55,10 @@ import java.util.*; public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabActionSupport, DumbAware { private static final Set ourArgumentListAllowedParentClassesSet = ContainerUtil.newHashSet( PsiMethodCallExpression.class, PsiNewExpression.class, PsiAnonymousClass.class, PsiEnumConstant.class); - private static final Set ourStopSearch = Collections.singleton(PsiMethod.class); private static final String WHITESPACE = " \t"; - - private Inlay myCurrentHint; - private List myHighlightedHints; + private static final Key CURRENT_HINT = Key.create("current.hint"); + private static final Key> HIGHLIGHTED_HINTS = Key.create("highlighted.hints"); @Override public Object[] getParametersForLookup(LookupElement item, ParameterInfoContext context) { @@ -155,14 +155,14 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc document != null && psiDocumentManager.isCommitted(document) && isIncompatibleParameterCount(chosenMethod, currentNumberOfParameters)) { JavaMethodCallElement.setCompletionMode((PsiCall)parent, false); - highlightHints(context.getEditor(), null, -1); + highlightHints(context.getEditor(), null, -1, context.getCustomContext()); } else { int index = ParameterInfoUtils.getCurrentParameterIndex(expressionList.getNode(), context.getOffset(), JavaTokenType.COMMA); TextRange textRange = expressionList.getTextRange(); if (context.getOffset() <= textRange.getStartOffset() || context.getOffset() >= textRange.getEndOffset()) index = -1; - highlightHints(context.getEditor(), expressionList, context.isInnermostContext() ? index : -1); + highlightHints(context.getEditor(), expressionList, context.isInnermostContext() ? index : -1, context.getCustomContext()); } } @@ -171,7 +171,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc } } } - highlightHints(context.getEditor(), null, -1); + highlightHints(context.getEditor(), null, -1, context.getCustomContext()); return null; } @@ -344,7 +344,8 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc } } - private void highlightHints(@NotNull Editor editor, @Nullable PsiExpressionList expressionList, int currentHintIndex) { + private static void highlightHints(@NotNull Editor editor, @Nullable PsiExpressionList expressionList, int currentHintIndex, + @NotNull UserDataHolder context) { if (editor.isDisposed()) return; ParameterHintsPresentationManager presentationManager = ParameterHintsPresentationManager.getInstance(); Inlay currentHint = null; @@ -396,37 +397,40 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc } } } - if (currentHint == myCurrentHint && Objects.equals(highlightedHints, myHighlightedHints)) return; - resetHints(); + if (currentHint == context.getUserData(CURRENT_HINT) && + Objects.equals(highlightedHints, context.getUserData(HIGHLIGHTED_HINTS))) return; + resetHints(context); if (currentHint != null) { presentationManager.setCurrent(currentHint, true); - myCurrentHint = currentHint; + context.putUserData(CURRENT_HINT, currentHint); } if (!ContainerUtil.isEmpty(highlightedHints)) { for (Inlay highlightedHint : highlightedHints) { presentationManager.setHighlighted(highlightedHint, true); } - myHighlightedHints = highlightedHints; + context.putUserData(HIGHLIGHTED_HINTS, highlightedHints); } } - private void resetHints() { + private static void resetHints(@NotNull UserDataHolder context) { ParameterHintsPresentationManager presentationManager = ParameterHintsPresentationManager.getInstance(); - if (myCurrentHint != null) { - presentationManager.setCurrent(myCurrentHint, false); - myCurrentHint = null; + Inlay currentHint = context.getUserData(CURRENT_HINT); + if (currentHint != null) { + presentationManager.setCurrent(currentHint, false); + context.putUserData(CURRENT_HINT, null); } - if (myHighlightedHints != null) { - for (Inlay hint : myHighlightedHints) { + List highlightedHints = context.getUserData(HIGHLIGHTED_HINTS); + if (highlightedHints != null) { + for (Inlay hint : highlightedHints) { presentationManager.setHighlighted(hint, false); } - myHighlightedHints = null; + context.putUserData(HIGHLIGHTED_HINTS, null); } } @Override - public void dispose() { - resetHints(); + public void dispose(@NotNull DeleteParameterInfoContext context) { + resetHints(context.getCustomContext()); } private static PsiSubstitutor getCandidateInfoSubstitutor(PsiElement argList, CandidateInfo candidate, boolean resolveResult) { diff --git a/platform/lang-api/src/com/intellij/lang/parameterInfo/DeleteParameterInfoContext.java b/platform/lang-api/src/com/intellij/lang/parameterInfo/DeleteParameterInfoContext.java new file mode 100644 index 000000000000..7bec57a7da4e --- /dev/null +++ b/platform/lang-api/src/com/intellij/lang/parameterInfo/DeleteParameterInfoContext.java @@ -0,0 +1,10 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.lang.parameterInfo; + +import com.intellij.openapi.util.UserDataHolderEx; + +public interface DeleteParameterInfoContext { + UserDataHolderEx getCustomContext(); +} diff --git a/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java b/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java index 385c9117f103..aa1ab6181de5 100644 --- a/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java +++ b/platform/lang-api/src/com/intellij/lang/parameterInfo/ParameterInfoHandler.java @@ -37,7 +37,7 @@ public interface ParameterInfoHandler { void updateUI(ParameterType p, @NotNull ParameterInfoUIContext context); default boolean supportsOverloadSwitching() { return false; } - default void dispose() {} + default void dispose(@NotNull DeleteParameterInfoContext context) {} /** @deprecated not used */ default @Nullable Object[] getParametersForDocumentation(ParameterType p, ParameterInfoContext context) { return null; } diff --git a/platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java b/platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java index 20b538037c57..87770dafcc19 100644 --- a/platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java +++ b/platform/lang-api/src/com/intellij/lang/parameterInfo/UpdateParameterInfoContext.java @@ -16,6 +16,7 @@ package com.intellij.lang.parameterInfo; +import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.psi.PsiElement; public interface UpdateParameterInfoContext extends ParameterInfoContext { @@ -37,4 +38,6 @@ public interface UpdateParameterInfoContext extends ParameterInfoContext { boolean isPreservedOnHintHidden(); void setPreservedOnHintHidden(boolean value); boolean isInnermostContext(); + + UserDataHolderEx getCustomContext(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java index 1a7e1144c7be..717b36c6d34a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoController.java @@ -11,10 +11,7 @@ import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.ide.IdeTooltip; import com.intellij.injected.editor.EditorWindow; -import com.intellij.lang.parameterInfo.ParameterInfoHandler; -import com.intellij.lang.parameterInfo.ParameterInfoHandlerWithTabActionSupport; -import com.intellij.lang.parameterInfo.ParameterInfoUtils; -import com.intellij.lang.parameterInfo.UpdateParameterInfoContext; +import com.intellij.lang.parameterInfo.*; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -29,10 +26,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.Balloon.Position; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; @@ -63,7 +57,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.LockSupport; -public class ParameterInfoController implements Disposable { +public class ParameterInfoController extends UserDataHolderBase implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.hint.ParameterInfoController"); private static final String WHITESPACE = " \t"; private final Project myProject; @@ -206,7 +200,7 @@ public class ParameterInfoController implements Disposable { if (myDisposed) return; myDisposed = true; myHint.hide(); - myHandler.dispose(); + myHandler.dispose(new MyDeleteParameterInfoContext()); List allControllers = getAllControllers(myEditor); allControllers.remove(this); myEditor.getCaretModel().removeCaretListener(myEditorCaretListener); @@ -668,6 +662,11 @@ public class ParameterInfoController implements Disposable { } return true; } + + @Override + public UserDataHolderEx getCustomContext() { + return ParameterInfoController.this; + } } private static class MyBestLocationPointProvider { @@ -742,4 +741,11 @@ public class ParameterInfoController implements Disposable { return getComponentCount() == 0 ? "" : getComponent(0).toString(); } } + + private class MyDeleteParameterInfoContext implements DeleteParameterInfoContext { + @Override + public UserDataHolderEx getCustomContext() { + return ParameterInfoController.this; + } + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/utils/parameterInfo/MockUpdateParameterInfoContext.java b/platform/testFramework/src/com/intellij/testFramework/utils/parameterInfo/MockUpdateParameterInfoContext.java index 2294b712d696..70a4ce61c9ef 100644 --- a/platform/testFramework/src/com/intellij/testFramework/utils/parameterInfo/MockUpdateParameterInfoContext.java +++ b/platform/testFramework/src/com/intellij/testFramework/utils/parameterInfo/MockUpdateParameterInfoContext.java @@ -18,6 +18,7 @@ package com.intellij.testFramework.utils.parameterInfo; import com.intellij.lang.parameterInfo.UpdateParameterInfoContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; @@ -104,6 +105,11 @@ public class MockUpdateParameterInfoContext implements UpdateParameterInfoContex return false; } + @Override + public UserDataHolderEx getCustomContext() { + throw new UnsupportedOperationException(); + } + public Project getProject() { return myFile.getProject(); } diff --git a/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java b/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java index e29412192fb1..91518ea8e364 100644 --- a/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java +++ b/python/testSrc/com/jetbrains/python/PyParameterInfoTest.java @@ -22,6 +22,7 @@ import com.intellij.lang.parameterInfo.UpdateParameterInfoContext; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -917,6 +918,11 @@ public class PyParameterInfoTest extends LightMarkedTestCase { return false; } + @Override + public UserDataHolderEx getCustomContext() { + throw new UnsupportedOperationException(); + } + @Override public PsiElement getHighlightedElement() { return null; // we don't use it