diff --git a/python/src/com/jetbrains/python/PyParameterInfoHandler.java b/python/src/com/jetbrains/python/PyParameterInfoHandler.java index 518051e25b80..e6ed68213dac 100644 --- a/python/src/com/jetbrains/python/PyParameterInfoHandler.java +++ b/python/src/com/jetbrains/python/PyParameterInfoHandler.java @@ -114,7 +114,7 @@ public class PyParameterInfoHandler implements ParameterInfoHandlerNote: instead of parameter index, we directly store parameter's offset for later use.
We cannot store an index since we cannot determine what is an argument until we actually map arguments to parameters. This is because a tuple in arguments may be a whole argument or map to a tuple parameter. @@ -182,26 +182,32 @@ public class PyParameterInfoHandler implements ParameterInfoHandler parameters = PyUtil.getParameters(markedCallee.getCallable(), typeEvalContext); - final List namedParameters = new ArrayList<>(parameters.size()); + final Map indexToNamedParameter = new HashMap<>(); // param -> hint index. indexes are not contiguous, because some hints are parentheses. - final Map parameterToIndex = new HashMap<>(); + final Map parameterToHintIndex = new HashMap<>(); // formatting of hints: hint index -> flags. this includes flags for parens. final Map> hintFlags = new HashMap<>(); - final List hintsList = buildParameterListHint(parameters, namedParameters, parameterToIndex, hintFlags, typeEvalContext); + final List hintsList = + buildParameterListHint(parameters, indexToNamedParameter, parameterToHintIndex, hintFlags, typeEvalContext); final int currentParamOffset = context.getCurrentParameterIndex(); // in Python mode, we get an offset here, not an index! // gray out enough first parameters as implicit (self, cls, ...) for (int i = 0; i < markedCallee.getImplicitOffset(); i++) { - hintFlags.get(parameterToIndex.get(namedParameters.get(i))).add(ParameterInfoUIContextEx.Flag.DISABLE); // show but mark as absent + if (indexToNamedParameter.containsKey(i)) { + final PyNamedParameter parameter = indexToNamedParameter.get(i); + hintFlags.get(parameterToHintIndex.get(parameter)).add(ParameterInfoUIContextEx.Flag.DISABLE); // show but mark as absent + } } final List flattenedArguments = PyUtil.flattenedParensAndLists(callExpression.getArguments()); - final int lastParamIndex = collectHighlights(mapping, parameters, parameterToIndex, hintFlags, flattenedArguments, currentParamOffset); + final int lastParamIndex = + collectHighlights(mapping, parameters, parameterToHintIndex, hintFlags, flattenedArguments, currentParamOffset); - highlightNext(markedCallee, parameters, namedParameters, parameterToIndex, hintFlags, flattenedArguments.isEmpty(), lastParamIndex); + highlightNext(markedCallee, parameters, indexToNamedParameter, parameterToHintIndex, hintFlags, flattenedArguments.isEmpty(), + lastParamIndex); String[] hints = ArrayUtil.toStringArray(hintsList); if (context instanceof ParameterInfoUIContextEx) { @@ -232,14 +238,15 @@ public class PyParameterInfoHandler implements ParameterInfoHandler parameterList, - @NotNull final List namedParameters, - @NotNull final Map parameterToIndex, + @NotNull final Map indexToNamedParameter, + @NotNull final Map parameterToHintIndex, @NotNull final Map> hintFlags, boolean isArgsEmpty, int lastParamIndex) { boolean canOfferNext = true; // can we highlight next unfilled parameter for (EnumSet set : hintFlags.values()) { - if (set.contains(ParameterInfoUIContextEx.Flag.HIGHLIGHT)) + if (set.contains(ParameterInfoUIContextEx.Flag.HIGHLIGHT)) { canOfferNext = false; + } } // highlight the next parameter to be filled if (canOfferNext) { @@ -248,7 +255,7 @@ public class PyParameterInfoHandler implements ParameterInfoHandler parameterList, - @NotNull final Map parameterToIndex, + @NotNull final Map parameterHintToIndex, @NotNull final Map> hintFlags, - @NotNull final List flatArgs, int currentParamOffset) { + @NotNull final List flatArgs, + int currentParamOffset) { final PyMarkedCallee callee = mapping.getMarkedCallee(); assert callee != null; int lastParamIndex = callee.getImplicitOffset(); @@ -292,19 +301,19 @@ public class PyParameterInfoHandler implements ParameterInfoHandler parameterToIndex, - @NotNull final Map> hintFlags, - boolean mustHighlight) { - final Integer parameterIndex = parameterToIndex.get(parameter); - if (mustHighlight && parameterIndex != null && parameterIndex < hintFlags.size()) { - hintFlags.get(parameterIndex).add(ParameterInfoUIContextEx.Flag.HIGHLIGHT); + @NotNull final Map parameterToHintIndex, + @NotNull final Map> hintFlags, + boolean mustHighlight) { + final Integer hintIndex = parameterToHintIndex.get(parameter); + if (mustHighlight && hintIndex != null && hintFlags.containsKey(hintIndex)) { + hintFlags.get(hintIndex).add(ParameterInfoUIContextEx.Flag.HIGHLIGHT); } } /** * builds the textual picture and the list of named parameters * - * @param parameters parameters of a callable - * @param namedParameters used to collect all named parameters of callable - * @param parameterToIndex used to collect info about parameter indexes - * @param hintFlags mark parameter as deprecated/highlighted/strikeout - * @param context context to be used to get parameter representation + * @param parameters parameters of a callable + * @param indexToNamedParameter used to collect all named parameters of callable + * @param parameterToHintIndex used to collect info about parameter hints + * @param hintFlags mark parameter as deprecated/highlighted/strikeout + * @param context context to be used to get parameter representation */ private static List buildParameterListHint(@NotNull List parameters, - @NotNull final List namedParameters, - @NotNull final Map parameterToIndex, + @NotNull final Map indexToNamedParameter, + @NotNull final Map parameterToHintIndex, @NotNull final Map> hintFlags, @NotNull TypeEvalContext context) { final List hintsList = new ArrayList<>(); + final int[] currentParameterIndex = new int[]{0}; ParamHelper.walkDownParamArray( parameters.toArray(new PyParameter[parameters.size()]), new ParamHelper.ParamWalker() { @@ -373,19 +383,21 @@ public class PyParameterInfoHandler implements ParameterInfoHandler