ParameterHints (@NotNull Pair<PyCallExpression, PyCallableType> callAndCallee, int currentParamOffset) { final PyCallExpression callExpression = callAndCallee.getFirst(); PyPsiUtils.assertValid(callExpression); final TypeEvalContext typeEvalContext = TypeEvalContext.codeAnalysis(callExpression.getProject(), callExpression.getContainingFile()); final PyCallableType callableType = callAndCallee.getSecond(); final List<PyCallableParameter> parameters = callableType.getParameters(typeEvalContext); if (parameters == null) return null; final PyCallExpression.PyArgumentsMapping mapping = PyCallExpressionHelper.mapArguments(callExpression, callableType, typeEvalContext); if (mapping.getCallableType() == null) return null; final Map<Integer, PyCallableParameter> indexToNamedParameter = new HashMap<>(parameters.size()); // param -> hint index. indexes are not contiguous, because some hints are parentheses. final Map<PyCallableParameter, Integer> parameterToHintIndex = new HashMap<>(); // formatting of hints: hint index -> flags. this includes flags for parens. final Map<Integer, EnumSet<ParameterFlag>> hintFlags = new HashMap<>(); final Pair<List<String>, List<String>> hintsAndAnnotations = buildParameterListHint(parameters, indexToNamedParameter, parameterToHintIndex, hintFlags, typeEvalContext); final List<String> hintsList = hintsAndAnnotations.first; final List<String> annotations = hintsAndAnnotations.second; highlightParameters(callExpression, callableType, parameters, mapping, indexToNamedParameter, parameterToHintIndex, hintFlags, currentParamOffset); return new ParameterHints(hintsList, hintFlags, annotations); }