use of com.jetbrains.python.psi.PyCallExpression.PyMarkedCallee in project intellij-community by JetBrains.
the class PyParameterInfoHandler method collectHighlights.
/**
* match params to available args, highlight current param(s)
*
* @return index of last parameter
*/
private static int collectHighlights(@NotNull final PyCallExpression.PyArgumentsMapping mapping, @NotNull final List<PyParameter> parameterList, @NotNull final Map<PyNamedParameter, Integer> parameterToIndex, @NotNull final Map<Integer, EnumSet<ParameterInfoUIContextEx.Flag>> hintFlags, @NotNull final List<PyExpression> flatArgs, int currentParamOffset) {
final PyMarkedCallee callee = mapping.getMarkedCallee();
assert callee != null;
int lastParamIndex = callee.getImplicitOffset();
final Map<PyExpression, PyNamedParameter> mappedParameters = mapping.getMappedParameters();
final Map<PyExpression, PyTupleParameter> mappedTupleParameters = mapping.getMappedTupleParameters();
for (PyExpression arg : flatArgs) {
final boolean mustHighlight = arg.getTextRange().contains(currentParamOffset);
PsiElement seeker = arg;
// An argument tuple may have been flattened; find it
while (!(seeker instanceof PyArgumentList) && seeker instanceof PyExpression && !mappedParameters.containsKey(seeker)) {
seeker = seeker.getParent();
}
if (seeker instanceof PyExpression) {
final PyNamedParameter parameter = mappedParameters.get((PyExpression) seeker);
lastParamIndex = Math.max(lastParamIndex, parameterList.indexOf(parameter));
if (parameter != null) {
highlightParameter(parameter, parameterToIndex, hintFlags, mustHighlight);
}
} else if (PyCallExpressionHelper.isVariadicPositionalArgument(arg)) {
for (PyNamedParameter parameter : mapping.getParametersMappedToVariadicPositionalArguments()) {
lastParamIndex = Math.max(lastParamIndex, parameterList.indexOf(parameter));
highlightParameter(parameter, parameterToIndex, hintFlags, mustHighlight);
}
} else if (PyCallExpressionHelper.isVariadicKeywordArgument(arg)) {
for (PyNamedParameter parameter : mapping.getParametersMappedToVariadicKeywordArguments()) {
lastParamIndex = Math.max(lastParamIndex, parameterList.indexOf(parameter));
highlightParameter(parameter, parameterToIndex, hintFlags, mustHighlight);
}
} else {
final PyTupleParameter tupleParameter = mappedTupleParameters.get(arg);
if (tupleParameter != null) {
for (PyNamedParameter parameter : getFlattenedTupleParameterComponents(tupleParameter)) {
lastParamIndex = Math.max(lastParamIndex, parameterList.indexOf(parameter));
highlightParameter(parameter, parameterToIndex, hintFlags, mustHighlight);
}
}
}
}
return lastParamIndex;
}
use of com.jetbrains.python.psi.PyCallExpression.PyMarkedCallee in project intellij-community by JetBrains.
the class PyParameterInfoHandler method updateUI.
@Override
public void updateUI(@NotNull Pair<PyCallExpression, PyMarkedCallee> callAndCallee, @NotNull ParameterInfoUIContext context) {
final PyCallExpression callExpression = callAndCallee.getFirst();
PyPsiUtils.assertValid(callExpression);
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(callExpression.getProject(), callExpression.getContainingFile());
final PyCallExpression.PyArgumentsMapping mapping = PyCallExpressionHelper.mapArguments(callExpression, callAndCallee.getSecond(), typeEvalContext);
final PyMarkedCallee markedCallee = mapping.getMarkedCallee();
if (markedCallee == null)
return;
final List<PyParameter> parameters = PyUtil.getParameters(markedCallee.getCallable(), typeEvalContext);
final List<PyNamedParameter> namedParameters = new ArrayList<>(parameters.size());
// param -> hint index. indexes are not contiguous, because some hints are parentheses.
final Map<PyNamedParameter, Integer> parameterToIndex = new HashMap<>();
// formatting of hints: hint index -> flags. this includes flags for parens.
final Map<Integer, EnumSet<ParameterInfoUIContextEx.Flag>> hintFlags = new HashMap<>();
final List<String> hintsList = buildParameterListHint(parameters, namedParameters, parameterToIndex, hintFlags, typeEvalContext);
// in Python mode, we get an offset here, not an index!
final int currentParamOffset = context.getCurrentParameterIndex();
// gray out enough first parameters as implicit (self, cls, ...)
for (int i = 0; i < markedCallee.getImplicitOffset(); i++) {
// show but mark as absent
hintFlags.get(parameterToIndex.get(namedParameters.get(i))).add(ParameterInfoUIContextEx.Flag.DISABLE);
}
final List<PyExpression> flattenedArguments = PyUtil.flattenedParensAndLists(callExpression.getArguments());
final int lastParamIndex = collectHighlights(mapping, parameters, parameterToIndex, hintFlags, flattenedArguments, currentParamOffset);
highlightNext(markedCallee, parameters, namedParameters, parameterToIndex, hintFlags, flattenedArguments.isEmpty(), lastParamIndex);
String[] hints = ArrayUtil.toStringArray(hintsList);
if (context instanceof ParameterInfoUIContextEx) {
final ParameterInfoUIContextEx pic = (ParameterInfoUIContextEx) context;
EnumSet[] flags = new EnumSet[hintFlags.size()];
for (int i = 0; i < flags.length; i++) flags[i] = hintFlags.get(i);
if (hints.length < 1) {
hints = new String[] { NO_PARAMS_MSG };
flags = new EnumSet[] { EnumSet.of(ParameterInfoUIContextEx.Flag.DISABLE) };
}
//noinspection unchecked
pic.setupUIComponentPresentation(hints, flags, context.getDefaultParameterColor());
} else {
// fallback, no highlight
final StringBuilder signatureBuilder = new StringBuilder();
if (hints.length > 1) {
for (String s : hints) signatureBuilder.append(s);
} else {
signatureBuilder.append(XmlStringUtil.escapeString(NO_PARAMS_MSG));
}
context.setupUIComponentPresentation(signatureBuilder.toString(), -1, 0, false, false, false, context.getDefaultParameterColor());
}
}
Aggregations