Changed the API for arguments-paramters mapping to PyCallExpression.mapArguments()

Moved CallArgumentsMappingImpl to PyCallExpressionHelper.mapArguments()
and switched from returning a map of mapped parameters to a class that
will contain more info about mappings.
This commit is contained in:
Andrey Vlasovskikh
2015-08-19 16:57:50 +03:00
parent 8afbcce2b3
commit 08148e87d7
12 changed files with 231 additions and 210 deletions
@@ -22,6 +22,8 @@ import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Represents an entire call expression, like <tt>foo()</tt> or <tt>foo.bar[1]('x')</tt>.
*/
@@ -114,6 +116,9 @@ public interface PyCallExpression extends PyCallSiteExpression {
@Nullable
PyMarkedCallee resolveCallee(PyResolveContext resolveContext, int implicitOffset);
@NotNull
PyArgumentsMapping mapArguments(@NotNull PyResolveContext resolveContext);
/**
* Checks if the unqualified name of the callee matches any of the specified names
*
@@ -122,7 +127,6 @@ public interface PyCallExpression extends PyCallSiteExpression {
*/
boolean isCalleeText(@NotNull String... nameCandidates);
/**
* Checks if the qualified name of the callee matches any of the specified names provided by provider.
* @see com.jetbrains.python.nameResolver
@@ -131,6 +135,26 @@ public interface PyCallExpression extends PyCallSiteExpression {
*/
boolean isCallee(@NotNull FQNamesProvider... name);
class PyArgumentsMapping {
@Nullable private final PyMarkedCallee myCallee;
@NotNull private final Map<PyExpression, PyNamedParameter> myMappedParameters;
public PyArgumentsMapping(@Nullable PyMarkedCallee markedCallee, @NotNull Map<PyExpression, PyNamedParameter> mappedParameters) {
myCallee = markedCallee;
myMappedParameters = mappedParameters;
}
@Nullable
public PyMarkedCallee getMarkedCallee() {
return myCallee;
}
@NotNull
public Map<PyExpression, PyNamedParameter> getMappedParameters() {
return myMappedParameters;
}
}
/**
* Couples function with a flag describing the way it is called.
*/
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiReference;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.inspections.quickfix.RemoveArgumentEqualDefaultQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.types.PyClassType;
import org.jetbrains.annotations.Nls;
@@ -98,9 +97,9 @@ public class PyArgumentEqualDefaultInspection extends PyInspection {
}
private void checkArguments(PyCallExpression callExpr, PyExpression[] arguments) {
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(callExpr, getResolveContext());
final PyCallExpression.PyArgumentsMapping mapping = callExpr.mapArguments(getResolveContext());
Set<PyExpression> problemElements = new HashSet<PyExpression>();
for (Map.Entry<PyExpression, PyNamedParameter> e : mapping.entrySet()) {
for (Map.Entry<PyExpression, PyNamedParameter> e : mapping.getMappedParameters().entrySet()) {
PyExpression defaultValue = e.getValue().getDefaultValue();
if (defaultValue != null) {
PyExpression key = e.getKey();
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.types.PyClassType;
import com.jetbrains.python.psi.types.PyType;
import org.jetbrains.annotations.Nls;
@@ -91,13 +90,13 @@ public class PyCallByClassInspection extends PyInspection {
PyClass qual_class = qual_class_type.getPyClass();
final PyArgumentList arglist = call.getArgumentList();
if (arglist != null) {
final PyCallExpression.PyMarkedCallee markedCallee = call.resolveCallee(getResolveContext());
final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(getResolveContext());
final PyCallExpression.PyMarkedCallee markedCallee = mapping.getMarkedCallee();
if (markedCallee != null && markedCallee.getModifier() != STATICMETHOD) {
final List<PyParameter> params = PyUtil.getParameters(markedCallee.getCallable(), myTypeEvalContext);
if (params.size() > 0 && params.get(0) instanceof PyNamedParameter) {
PyNamedParameter first_param = (PyNamedParameter)params.get(0);
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(call, getResolveContext());
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.entrySet()) {
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.getMappedParameters().entrySet()) {
// we ignore *arg and **arg which we cannot analyze
if (entry.getValue() == first_param) {
PyExpression first_arg = entry.getKey();
@@ -34,7 +34,6 @@ import com.jetbrains.python.PyNames;
import com.jetbrains.python.inspections.quickfix.PyUpdatePropertySignatureQuickFix;
import com.jetbrains.python.inspections.quickfix.RenameParameterQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.types.PyClassType;
import com.jetbrains.python.psi.types.PyNoneType;
@@ -121,8 +120,8 @@ public class PyPropertyDefinitionInspection extends PyInspection {
final PyArgumentList arglist = call.getArgumentList();
assert arglist != null : "Property call has null arglist";
// we assume fget, fset, fdel, doc names
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(call, getResolveContext());
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.entrySet()) {
final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(getResolveContext());
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.getMappedParameters().entrySet()) {
final String paramName = entry.getValue().getName();
PyExpression argument = PyUtil.peelArgument(entry.getKey());
checkPropertyCallArgument(paramName, argument, node.getContainingFile());
@@ -27,7 +27,6 @@ import com.jetbrains.python.PyBundle;
import com.jetbrains.python.documentation.PyDocumentationSettings;
import com.jetbrains.python.editor.PythonDocCommentUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.refactoring.PyRefactoringUtil;
import org.jetbrains.annotations.NonNls;
@@ -64,9 +63,9 @@ public class PyRemoveParameterQuickFix implements LocalQuickFix {
if (callExpression instanceof PyCallExpression) {
final PyArgumentList argumentList = ((PyCallExpression)callExpression).getArgumentList();
if (argumentList != null) {
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map((PyCallExpression)callExpression,
PyResolveContext.noImplicits());
for (Map.Entry<PyExpression, PyNamedParameter> parameterEntry : mapping.entrySet()) {
final PyResolveContext resolveContext = PyResolveContext.noImplicits();
final PyCallExpression.PyArgumentsMapping mapping = ((PyCallExpression)callExpression).mapArguments(resolveContext);
for (Map.Entry<PyExpression, PyNamedParameter> parameterEntry : mapping.getMappedParameters().entrySet()) {
if (parameterEntry.getValue().equals(element)) {
parameterEntry.getKey().delete();
}
@@ -18,7 +18,6 @@ package com.jetbrains.python.psi.impl;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.types.PyTupleType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
@@ -55,180 +54,6 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
myArgumentList = arglist;
}
@NotNull
public static Map<PyExpression, PyNamedParameter> map(@NotNull PyCallExpression callExpression,
@NotNull PyResolveContext resolveContext) {
return map(callExpression, 0, resolveContext);
}
@NotNull
public static Map<PyExpression, PyNamedParameter> map(@NotNull PyCallExpression callExpression,
int implicitArgumentOffset,
@NotNull PyResolveContext resolveContext) {
final Map<PyExpression, PyNamedParameter> results = new LinkedHashMap<PyExpression, PyNamedParameter>();
final PyArgumentList argumentList = callExpression.getArgumentList();
final PyCallExpression.PyMarkedCallee markedCallee = callExpression.resolveCallee(resolveContext, implicitArgumentOffset);
if (markedCallee != null && argumentList != null) {
final TypeEvalContext context = resolveContext.getTypeEvalContext();
final List<PyParameter> allParameters = PyUtil.getParameters(markedCallee.getCallable(), context);
final List<PyParameter> parameters = dropImplicitParameters(allParameters, markedCallee.getImplicitOffset());
final List<PyExpression> arguments = Arrays.asList(argumentList.getArguments());
final List<PyExpression> positionalArguments = filterPositionalArguments(arguments);
final List<PyKeywordArgument> keywordArguments = filterKeywordArguments(arguments);
final List<PyExpression> variadicPositionalArguments = filterVariadicPositionalArguments(arguments);
final List<PyExpression> variadicKeywordArguments = filterVariadicKeywordArguments(arguments);
boolean seenSingleStar = false;
final List<PyParameter> unmappedParameters = new ArrayList<PyParameter>();
for (PyParameter parameter : parameters) {
if (parameter instanceof PyNamedParameter) {
final PyNamedParameter namedParameter = (PyNamedParameter)parameter;
final String parameterName = namedParameter.getName();
if (namedParameter.isPositionalContainer()) {
if (variadicPositionalArguments.size() == 1) {
results.put(variadicPositionalArguments.remove(0), namedParameter);
}
else {
positionalArguments.clear();
variadicPositionalArguments.clear();
}
}
else if (namedParameter.isKeywordContainer()) {
if (variadicKeywordArguments.size() == 1) {
results.put(variadicKeywordArguments.remove(0), namedParameter);
}
else {
keywordArguments.clear();
variadicKeywordArguments.clear();
}
}
else if (seenSingleStar) {
final PyExpression keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
if (keywordArgument != null) {
results.put(keywordArgument, namedParameter);
}
else if (variadicKeywordArguments.isEmpty()) {
unmappedParameters.add(namedParameter);
}
}
else {
if (!positionalArguments.isEmpty()) {
final PyExpression positionalArgument = next(positionalArguments);
if (positionalArgument != null) {
results.put(positionalArgument, namedParameter);
}
else {
unmappedParameters.add(namedParameter);
}
}
else {
final PyKeywordArgument keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
if (keywordArgument != null) {
results.put(keywordArgument, namedParameter);
}
else if (variadicPositionalArguments.isEmpty() || variadicKeywordArguments.isEmpty()) {
unmappedParameters.add(namedParameter);
}
}
}
}
else if (parameter instanceof PyTupleParameter) {
unmappedParameters.add(parameter);
}
else if (parameter instanceof PySingleStarParameter) {
seenSingleStar = true;
}
else {
unmappedParameters.add(parameter);
}
}
}
return results;
}
@Nullable
private static PyKeywordArgument removeKeywordArgument(@NotNull List<PyKeywordArgument> arguments, @Nullable String name) {
PyKeywordArgument result = null;
for (PyKeywordArgument argument : arguments) {
final String keyword = argument.getKeyword();
if (keyword != null && keyword.equals(name)) {
result = argument;
break;
}
}
if (result != null) {
arguments.remove(result);
}
return result;
}
@NotNull
private static List<PyExpression> filterPositionalArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (isPositionalArg(argument)) {
results.add(argument);
}
}
return results;
}
@NotNull
private static List<PyKeywordArgument> filterKeywordArguments(@NotNull List<PyExpression> arguments) {
final List<PyKeywordArgument> results = new ArrayList<PyKeywordArgument>();
for (PyExpression argument : arguments) {
if (argument instanceof PyKeywordArgument) {
results.add((PyKeywordArgument)argument);
}
}
return results;
}
@NotNull
private static List<PyExpression> filterVariadicPositionalArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (argument != null && isVariadicPositionalArgument(argument)) {
results.add(argument);
}
}
return results;
}
@NotNull
private static List<PyExpression> filterVariadicKeywordArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (argument != null && isVariadicKeywordArgument(argument)) {
results.add(argument);
}
}
return results;
}
private static boolean isVariadicKeywordArgument(@NotNull PyExpression argument) {
return argument instanceof PyStarArgument && ((PyStarArgument)argument).isKeyword();
}
private static boolean isVariadicPositionalArgument(@NotNull PyExpression argument) {
return argument instanceof PyStarArgument && !((PyStarArgument)argument).isKeyword();
}
@Nullable
private static <T> T next(@NotNull List<T> list) {
return list.isEmpty() ? null : list.remove(0);
}
@NotNull
private static List<PyParameter> dropImplicitParameters(@NotNull List<PyParameter> parameters, int offset) {
final ArrayList<PyParameter> results = new ArrayList<PyParameter>(parameters);
for (int i = 0; i < offset && !results.isEmpty(); i++) {
results.remove(0);
}
return results;
}
/**
* Maps arguments of a call to parameters of a callee.
* must contain already resolved callee with flags set appropriately.
@@ -423,11 +248,11 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
// NOTE: ignores the structure of nested-tuple params!
if (tuple_par != null) {
i = 0;
while (i < arguments.length && mapped_args.contains(arguments[i]) && isPositionalArg(arguments[i])) {
while (i < arguments.length && mapped_args.contains(arguments[i]) && PyCallExpressionHelper.isPositionalArgument(arguments[i])) {
i += 1; // skip first mapped args
}
if (i < arguments.length && isPositionalArg(arguments[i])) {
while (i < arguments.length && !mapped_args.contains(arguments[i]) && isPositionalArg(arguments[i])) {
if (i < arguments.length && PyCallExpressionHelper.isPositionalArgument(arguments[i])) {
while (i < arguments.length && !mapped_args.contains(arguments[i]) && PyCallExpressionHelper.isPositionalArgument(arguments[i])) {
myPlainMappedParams.put(arguments[i], tuple_par);
mapped_args.add(arguments[i]);
i += 1;
@@ -550,10 +375,6 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping {
}
}
private static boolean isPositionalArg(PyExpression arg) {
return !(arg instanceof PyKeywordArgument) && !(arg instanceof PyStarArgument);
}
/**
* @return A mapping argument->parameter for non-starred arguments (but includes starred parameters).
*/
@@ -631,4 +631,175 @@ public class PyCallExpressionHelper {
final PyExpression callee = expression.getCallee();
return (callee != null) && NameResolverTools.isName(callee, namesProviders);
}
@NotNull
public static PyCallExpression.PyArgumentsMapping mapArguments(@NotNull PyCallExpression callExpression,
@NotNull PyResolveContext resolveContext) {
final Map<PyExpression, PyNamedParameter> mappedParameters = new LinkedHashMap<PyExpression, PyNamedParameter>();
final PyArgumentList argumentList = callExpression.getArgumentList();
final PyCallExpression.PyMarkedCallee markedCallee = callExpression.resolveCallee(resolveContext);
if (markedCallee != null && argumentList != null) {
final TypeEvalContext context = resolveContext.getTypeEvalContext();
final List<PyParameter> allParameters = PyUtil.getParameters(markedCallee.getCallable(), context);
final List<PyParameter> parameters = dropImplicitParameters(allParameters, markedCallee.getImplicitOffset());
final List<PyExpression> arguments = Arrays.asList(argumentList.getArguments());
final List<PyExpression> positionalArguments = filterPositionalArguments(arguments);
final List<PyKeywordArgument> keywordArguments = filterKeywordArguments(arguments);
final List<PyExpression> variadicPositionalArguments = filterVariadicPositionalArguments(arguments);
final List<PyExpression> variadicKeywordArguments = filterVariadicKeywordArguments(arguments);
boolean seenSingleStar = false;
final List<PyParameter> unmappedParameters = new ArrayList<PyParameter>();
for (PyParameter parameter : parameters) {
if (parameter instanceof PyNamedParameter) {
final PyNamedParameter namedParameter = (PyNamedParameter)parameter;
final String parameterName = namedParameter.getName();
if (namedParameter.isPositionalContainer()) {
if (variadicPositionalArguments.size() == 1) {
mappedParameters.put(variadicPositionalArguments.remove(0), namedParameter);
}
else {
positionalArguments.clear();
variadicPositionalArguments.clear();
}
}
else if (namedParameter.isKeywordContainer()) {
if (variadicKeywordArguments.size() == 1) {
mappedParameters.put(variadicKeywordArguments.remove(0), namedParameter);
}
else {
keywordArguments.clear();
variadicKeywordArguments.clear();
}
}
else if (seenSingleStar) {
final PyExpression keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
if (keywordArgument != null) {
mappedParameters.put(keywordArgument, namedParameter);
}
else if (variadicKeywordArguments.isEmpty()) {
unmappedParameters.add(namedParameter);
}
}
else {
if (!positionalArguments.isEmpty()) {
final PyExpression positionalArgument = next(positionalArguments);
if (positionalArgument != null) {
mappedParameters.put(positionalArgument, namedParameter);
}
else {
unmappedParameters.add(namedParameter);
}
}
else {
final PyKeywordArgument keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
if (keywordArgument != null) {
mappedParameters.put(keywordArgument, namedParameter);
}
else if (variadicPositionalArguments.isEmpty() || variadicKeywordArguments.isEmpty()) {
unmappedParameters.add(namedParameter);
}
}
}
}
else if (parameter instanceof PyTupleParameter) {
unmappedParameters.add(parameter);
}
else if (parameter instanceof PySingleStarParameter) {
seenSingleStar = true;
}
else {
unmappedParameters.add(parameter);
}
}
}
return new PyCallExpression.PyArgumentsMapping(markedCallee, mappedParameters);
}
@Nullable
private static PyKeywordArgument removeKeywordArgument(@NotNull List<PyKeywordArgument> arguments, @Nullable String name) {
PyKeywordArgument result = null;
for (PyKeywordArgument argument : arguments) {
final String keyword = argument.getKeyword();
if (keyword != null && keyword.equals(name)) {
result = argument;
break;
}
}
if (result != null) {
arguments.remove(result);
}
return result;
}
@NotNull
private static List<PyExpression> filterPositionalArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (isPositionalArgument(argument)) {
results.add(argument);
}
}
return results;
}
@NotNull
private static List<PyKeywordArgument> filterKeywordArguments(@NotNull List<PyExpression> arguments) {
final List<PyKeywordArgument> results = new ArrayList<PyKeywordArgument>();
for (PyExpression argument : arguments) {
if (argument instanceof PyKeywordArgument) {
results.add((PyKeywordArgument)argument);
}
}
return results;
}
@NotNull
private static List<PyExpression> filterVariadicPositionalArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (argument != null && isVariadicPositionalArgument(argument)) {
results.add(argument);
}
}
return results;
}
@NotNull
private static List<PyExpression> filterVariadicKeywordArguments(@NotNull List<PyExpression> arguments) {
final List<PyExpression> results = new ArrayList<PyExpression>();
for (PyExpression argument : arguments) {
if (argument != null && isVariadicKeywordArgument(argument)) {
results.add(argument);
}
}
return results;
}
private static boolean isVariadicKeywordArgument(@NotNull PyExpression argument) {
return argument instanceof PyStarArgument && ((PyStarArgument)argument).isKeyword();
}
private static boolean isVariadicPositionalArgument(@NotNull PyExpression argument) {
return argument instanceof PyStarArgument && !((PyStarArgument)argument).isKeyword();
}
@Nullable
private static <T> T next(@NotNull List<T> list) {
return list.isEmpty() ? null : list.remove(0);
}
@NotNull
private static List<PyParameter> dropImplicitParameters(@NotNull List<PyParameter> parameters, int offset) {
final ArrayList<PyParameter> results = new ArrayList<PyParameter>(parameters);
for (int i = 0; i < offset && !results.isEmpty(); i++) {
results.remove(0);
}
return results;
}
static boolean isPositionalArgument(@Nullable PyExpression argument) {
return !(argument instanceof PyKeywordArgument) && !(argument instanceof PyStarArgument);
}
}
@@ -102,6 +102,12 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
return PyCallExpressionHelper.resolveCallee(this, resolveContext, offset);
}
@NotNull
@Override
public PyArgumentsMapping mapArguments(@NotNull PyResolveContext resolveContext) {
return PyCallExpressionHelper.mapArguments(this, resolveContext);
}
@Override
public boolean isCalleeText(@NotNull String... nameCandidates) {
return PyCallExpressionHelper.isCalleeText(this, nameCandidates);
@@ -157,6 +157,12 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase<PyDecoratorStub> im
return callee;
}
@NotNull
@Override
public PyArgumentsMapping mapArguments(@NotNull PyResolveContext resolveContext) {
return PyCallExpressionHelper.mapArguments(this, resolveContext);
}
@Override
public PyCallable resolveCalleeFunction(PyResolveContext resolveContext) {
return PyCallExpressionHelper.resolveCalleeFunction(this, resolveContext);
@@ -269,8 +269,8 @@ public class PyNamedParameterImpl extends PyBaseElementImpl<PyNamedParameterStub
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final PyArgumentList argumentList = call.getArgumentList();
if (argumentList != null) {
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(call, resolveContext);
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.entrySet()) {
final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(resolveContext);
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.getMappedParameters().entrySet()) {
if (entry.getValue() == PyNamedParameterImpl.this) {
final PyExpression argument = entry.getKey();
if (argument != null) {
@@ -393,8 +393,8 @@ public class PyNamedParameterImpl extends PyBaseElementImpl<PyNamedParameterStub
}
}
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(callExpression, resolveContext);
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.entrySet()) {
final PyCallExpression.PyArgumentsMapping mapping = callExpression.mapArguments(resolveContext);
for (Map.Entry<PyExpression, PyNamedParameter> entry : mapping.getMappedParameters().entrySet()) {
if (entry.getKey() == element) {
return entry.getValue();
}
@@ -24,7 +24,6 @@ import com.intellij.util.ArrayUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
@@ -458,8 +457,8 @@ public class PyTypeChecker {
final PyArgumentList args = call.getArgumentList();
if (args != null) {
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final Map<PyExpression, PyNamedParameter> arguments = CallArgumentsMappingImpl.map(call, resolveContext);
final PyCallExpression.PyMarkedCallee markedCallee = call.resolveCallee(resolveContext);
final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(resolveContext);
final PyCallExpression.PyMarkedCallee markedCallee = mapping.getMarkedCallee();
if (markedCallee != null) {
final PyCallable callable = markedCallee.getCallable();
if (callable instanceof PyFunction) {
@@ -474,7 +473,7 @@ public class PyTypeChecker {
else {
receiver = null;
}
return new AnalyzeCallResults(callable, receiver, arguments);
return new AnalyzeCallResults(callable, receiver, mapping.getMappedParameters());
}
}
}
@@ -47,7 +47,6 @@ import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.PythonStringUtil;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.CallArgumentsMappingImpl;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.types.PyNoneType;
import com.jetbrains.python.psi.types.PyType;
@@ -229,10 +228,9 @@ abstract public class IntroduceHandler implements RefactoringActionHandler {
final PyCallExpression callExpr = argList.getCallExpression();
if (callExpr != null) {
final PyResolveContext resolveContext = PyResolveContext.noImplicits();
final PyCallExpression.PyMarkedCallee markedCallee = callExpr.resolveCallee(resolveContext);
if (markedCallee != null) {
final Map<PyExpression, PyNamedParameter> mapping = CallArgumentsMappingImpl.map(callExpr, resolveContext);
final PyNamedParameter namedParameter = mapping.get(expression);
final PyCallExpression.PyArgumentsMapping mapping = callExpr.mapArguments(resolveContext);
if (mapping.getMarkedCallee() != null) {
final PyNamedParameter namedParameter = mapping.getMappedParameters().get(expression);
if (namedParameter != null) {
candidates.add(namedParameter.getName());
}