ArgumentMappingResults (@NotNull List<PyExpression> arguments, @NotNull List<PyCallableParameter> parameters, @NotNull TypeEvalContext context) { boolean positionalOnlyMode = ContainerUtil.exists(parameters, p -> p.getParameter() instanceof PySlashParameter); boolean seenSingleStar = false; boolean mappedVariadicArgumentsToParameters = false; final Map<PyExpression, PyCallableParameter> mappedParameters = new LinkedHashMap<>(); final List<PyCallableParameter> unmappedParameters = new ArrayList<>(); final List<PyCallableParameter> unmappedContainerParameters = new ArrayList<>(); final List<PyExpression> unmappedArguments = new ArrayList<>(); final List<PyCallableParameter> parametersMappedToVariadicKeywordArguments = new ArrayList<>(); final List<PyCallableParameter> parametersMappedToVariadicPositionalArguments = new ArrayList<>(); final Map<PyExpression, PyCallableParameter> tupleMappedParameters = new LinkedHashMap<>(); final PositionalArgumentsAnalysisResults positionalResults = filterPositionalAndVariadicArguments(arguments); final List<PyKeywordArgument> keywordArguments = filterKeywordArguments(arguments); final List<PyExpression> variadicPositionalArguments = positionalResults.variadicPositionalArguments; final Set<PyExpression> positionalComponentsOfVariadicArguments = new LinkedHashSet<>(positionalResults.componentsOfVariadicPositionalArguments); final List<PyExpression> variadicKeywordArguments = filterVariadicKeywordArguments(arguments); final List<PyExpression> allPositionalArguments = positionalResults.allPositionalArguments; for (PyCallableParameter parameter : parameters) { final PyParameter psi = parameter.getParameter(); if (psi instanceof PyNamedParameter || psi == null) { final String parameterName = parameter.getName(); if (parameter.isPositionalContainer()) { for (PyExpression argument : allPositionalArguments) { if (argument != null) { mappedParameters.put(argument, parameter); } } if (variadicPositionalArguments.size() == 1) { mappedParameters.put(variadicPositionalArguments.get(0), parameter); } if (variadicPositionalArguments.size() != 1 && allPositionalArguments.size() == 0) { unmappedContainerParameters.add(parameter); } allPositionalArguments.clear(); variadicPositionalArguments.clear(); } else if (parameter.isKeywordContainer()) { for (PyKeywordArgument argument : keywordArguments) { mappedParameters.put(argument, parameter); } for (PyExpression variadicKeywordArg : variadicKeywordArguments) { mappedParameters.put(variadicKeywordArg, parameter); } keywordArguments.clear(); variadicKeywordArguments.clear(); } else if (seenSingleStar) { final PyExpression keywordArgument = removeKeywordArgument(keywordArguments, parameterName); if (keywordArgument != null) { mappedParameters.put(keywordArgument, parameter); } else if (variadicKeywordArguments.isEmpty()) { if (!parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } } else { parametersMappedToVariadicKeywordArguments.add(parameter); mappedVariadicArgumentsToParameters = true; } } else if (isParamSpecOrConcatenate(parameter, context)) { for (var argument: arguments) { mappedParameters.put(argument, parameter); } allPositionalArguments.clear(); keywordArguments.clear(); variadicPositionalArguments.clear(); variadicKeywordArguments.clear(); } else { if (positionalOnlyMode) { final PyExpression positionalArgument = next(allPositionalArguments); if (positionalArgument != null) { mappedParameters.put(positionalArgument, parameter); } else if (!parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } } else if (allPositionalArguments.isEmpty()) { final PyKeywordArgument keywordArgument = removeKeywordArgument(keywordArguments, parameterName); if (keywordArgument != null) { mappedParameters.put(keywordArgument, parameter); } else if (variadicPositionalArguments.isEmpty() && variadicKeywordArguments.isEmpty() && !parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } else { if (!variadicPositionalArguments.isEmpty()) { parametersMappedToVariadicPositionalArguments.add(parameter); } if (!variadicKeywordArguments.isEmpty()) { parametersMappedToVariadicKeywordArguments.add(parameter); } mappedVariadicArgumentsToParameters = true; } } else { final PyExpression positionalArgument = next(allPositionalArguments); if (positionalArgument != null) { mappedParameters.put(positionalArgument, parameter); if (positionalComponentsOfVariadicArguments.contains(positionalArgument)) { parametersMappedToVariadicPositionalArguments.add(parameter); } } else if (!parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } } } } else if (psi instanceof PyTupleParameter) { final PyExpression positionalArgument = next(allPositionalArguments); if (positionalArgument != null) { tupleMappedParameters.put(positionalArgument, parameter); final TupleMappingResults tupleMappingResults = mapComponentsOfTupleParameter(positionalArgument, (PyTupleParameter)psi); mappedParameters.putAll(tupleMappingResults.getParameters()); unmappedParameters.addAll(tupleMappingResults.getUnmappedParameters()); unmappedArguments.addAll(tupleMappingResults.getUnmappedArguments()); } else if (variadicPositionalArguments.isEmpty()) { if (!parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } } else { mappedVariadicArgumentsToParameters = true; } } else if (psi instanceof PySlashParameter) { positionalOnlyMode = false; } else if (psi instanceof PySingleStarParameter) { seenSingleStar = true; } else if (!parameter.hasDefaultValue()) { unmappedParameters.add(parameter); } } if (mappedVariadicArgumentsToParameters) { variadicPositionalArguments.clear(); variadicKeywordArguments.clear(); } unmappedArguments.addAll(allPositionalArguments); unmappedArguments.addAll(keywordArguments); unmappedArguments.addAll(variadicPositionalArguments); unmappedArguments.addAll(variadicKeywordArguments); return new ArgumentMappingResults(mappedParameters, unmappedParameters, unmappedContainerParameters, unmappedArguments, parametersMappedToVariadicPositionalArguments, parametersMappedToVariadicKeywordArguments, tupleMappedParameters); }