keep ParameterInfoHandler instances stateless

move state from MethodParameterInfoHandler to controller (ParameterInfoController)
This commit is contained in:
Dmitry Batrak
2018-01-16 12:25:02 +03:00
parent 86f30656a2
commit bdb86162aa
7 changed files with 67 additions and 32 deletions
@@ -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<PsiExpressionList, Object, PsiExpression>, DumbAware {
private static final Set<Class> ourArgumentListAllowedParentClassesSet = ContainerUtil.newHashSet(
PsiMethodCallExpression.class, PsiNewExpression.class, PsiAnonymousClass.class, PsiEnumConstant.class);
private static final Set<? extends Class> ourStopSearch = Collections.singleton(PsiMethod.class);
private static final String WHITESPACE = " \t";
private Inlay myCurrentHint;
private List<Inlay> myHighlightedHints;
private static final Key<Inlay> CURRENT_HINT = Key.create("current.hint");
private static final Key<List<Inlay>> 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<Inlay> 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) {
@@ -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();
}
@@ -37,7 +37,7 @@ public interface ParameterInfoHandler <ParameterOwner, ParameterType> {
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; }
@@ -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();
}
@@ -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<ParameterInfoController> 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 ? "<empty>" : getComponent(0).toString();
}
}
private class MyDeleteParameterInfoContext implements DeleteParameterInfoContext {
@Override
public UserDataHolderEx getCustomContext() {
return ParameterInfoController.this;
}
}
}
@@ -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();
}
@@ -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