void (@NotNull final PsiExpressionList o, @NotNull final UpdateParameterInfoContext context) { int offset = context.getOffset(); TextRange elRange = o.getTextRange(); int index = offset <= elRange.getStartOffset() || offset >= elRange.getEndOffset() ? -1 : ParameterInfoUtils.getCurrentParameterIndex(o.getNode(), offset, JavaTokenType.COMMA); context.setCurrentParameter(index); Object[] candidates = context.getObjectsToView(); PsiExpression[] args = o.getExpressions(); PsiCall call = getCall(o); PsiElement realResolve = call != null ? call.resolveMethod() : null; PsiMethod chosenMethod = CompletionMemory.getChosenMethod(call); CandidateWithPresentation chosenInfo = null; CandidateWithPresentation completeMatch = null; for (int i = 0; i < candidates.length; i++) { CandidateWithPresentation candidateWithPresentation = (CandidateWithPresentation)candidates[i]; CandidateInfo candidate = candidateWithPresentation.candidateInfo; PsiMethod method = candidateWithPresentation.getMethod(); if (!method.isValid()) continue; if (candidate instanceof MethodCandidateInfo methodCandidateInfo && !methodCandidateInfo.getSiteSubstitutor().isValid()) continue; PsiSubstitutor substitutor = getCandidateInfoSubstitutor(candidate, method == realResolve); assert substitutor != null; if (!method.isValid() || !substitutor.isValid()) { // this may sometimes happen e,g, when editing method call in field initializer candidates in the same file get invalidated context.setUIComponentEnabled(i, false); continue; } PsiParameter[] parms = method.getParameterList().getParameters(); boolean enabled = true; if (parms.length <= index) { if (parms.length > 0) { if (method.isVarArgs()) { for (int j = 0; j < parms.length - 1; j++) { PsiType parmType = substitutor.substitute(parms[j].getType()); PsiType argType = args[j].getType(); if (argType != null && !parmType.isAssignableFrom(argType)) { enabled = false; break; } } if (enabled) { PsiArrayType lastParmType = (PsiArrayType)substitutor.substitute(parms[parms.length - 1].getType()); PsiType componentType = lastParmType.getComponentType(); if (parms.length == args.length) { PsiType lastArgType = args[args.length - 1].getType(); if (lastArgType != null && !lastParmType.isAssignableFrom(lastArgType) && !componentType.isAssignableFrom(lastArgType)) { enabled = false; } } else { for (int j = parms.length; j <= index && j < args.length; j++) { PsiExpression arg = args[j]; PsiType argType = arg.getType(); if (argType != null && !componentType.isAssignableFrom(argType)) { enabled = false; break; } } } } } else { enabled = false; } } else { enabled = index == 0; } } else { enabled = isAssignableParametersBeforeGivenIndex(parms, args, index, substitutor); } context.setUIComponentEnabled(i, enabled); if (candidates.length > 1 && enabled) { if (PsiManager.getInstance(context.getProject()).areElementsEquivalent(chosenMethod, method)) { chosenInfo = candidateWithPresentation; } if (realResolve == method) { if (parms.length == args.length && isAssignableParametersBeforeGivenIndex(parms, args, args.length, substitutor) || method.isVarArgs() && parms.length - 1 <= args.length && isAssignableParametersBeforeGivenIndex(parms, args, Math.min(parms.length, args.length), substitutor)) { completeMatch = candidateWithPresentation; } } } } CandidateWithPresentation parameterToHighlight = chosenInfo; if (completeMatch != null && (chosenInfo == null || (args.length > 0 && !(context.isPreservedOnHintHidden() && Registry.is("editor.completion.hints.virtual.comma") && completeMatch.presentation().parameters().size() < chosenInfo.presentation().parameters().size())))) { parameterToHighlight = completeMatch; } context.setHighlightedParameter(parameterToHighlight); Object highlightedCandidate = candidates.length == 1 ? candidates[0] : context.getHighlightedParameter(); if (highlightedCandidate != null) { PsiMethod method = getMethodFromCandidate(highlightedCandidate); if (!method.isVarArgs() && index > 0 && index >= method.getParameterList().getParametersCount()) { context.setCurrentParameter(-1); } } }