diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
index a2e0a1cb6a42..1a130c734f33 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
@@ -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 foo() or foo.bar[1]('x').
*/
@@ -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 myMappedParameters;
+
+ public PyArgumentsMapping(@Nullable PyMarkedCallee markedCallee, @NotNull Map mappedParameters) {
+ myCallee = markedCallee;
+ myMappedParameters = mappedParameters;
+ }
+
+ @Nullable
+ public PyMarkedCallee getMarkedCallee() {
+ return myCallee;
+ }
+
+ @NotNull
+ public Map getMappedParameters() {
+ return myMappedParameters;
+ }
+ }
+
/**
* Couples function with a flag describing the way it is called.
*/
diff --git a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
index 0250f439ccac..cd06a6d19e81 100644
--- a/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyArgumentEqualDefaultInspection.java
@@ -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 mapping = CallArgumentsMappingImpl.map(callExpr, getResolveContext());
+ final PyCallExpression.PyArgumentsMapping mapping = callExpr.mapArguments(getResolveContext());
Set problemElements = new HashSet();
- for (Map.Entry e : mapping.entrySet()) {
+ for (Map.Entry e : mapping.getMappedParameters().entrySet()) {
PyExpression defaultValue = e.getValue().getDefaultValue();
if (defaultValue != null) {
PyExpression key = e.getKey();
diff --git a/python/src/com/jetbrains/python/inspections/PyCallByClassInspection.java b/python/src/com/jetbrains/python/inspections/PyCallByClassInspection.java
index 6a73b89829ad..bbce4a658b25 100644
--- a/python/src/com/jetbrains/python/inspections/PyCallByClassInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyCallByClassInspection.java
@@ -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 params = PyUtil.getParameters(markedCallee.getCallable(), myTypeEvalContext);
if (params.size() > 0 && params.get(0) instanceof PyNamedParameter) {
PyNamedParameter first_param = (PyNamedParameter)params.get(0);
- final Map mapping = CallArgumentsMappingImpl.map(call, getResolveContext());
- for (Map.Entry entry : mapping.entrySet()) {
+ for (Map.Entry entry : mapping.getMappedParameters().entrySet()) {
// we ignore *arg and **arg which we cannot analyze
if (entry.getValue() == first_param) {
PyExpression first_arg = entry.getKey();
diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
index 406889e39058..80cade67f175 100644
--- a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
@@ -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 mapping = CallArgumentsMappingImpl.map(call, getResolveContext());
- for (Map.Entry entry : mapping.entrySet()) {
+ final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(getResolveContext());
+ for (Map.Entry entry : mapping.getMappedParameters().entrySet()) {
final String paramName = entry.getValue().getName();
PyExpression argument = PyUtil.peelArgument(entry.getKey());
checkPropertyCallArgument(paramName, argument, node.getContainingFile());
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveParameterQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveParameterQuickFix.java
index f25d013664bf..7e942a445ece 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveParameterQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveParameterQuickFix.java
@@ -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 mapping = CallArgumentsMappingImpl.map((PyCallExpression)callExpression,
- PyResolveContext.noImplicits());
- for (Map.Entry parameterEntry : mapping.entrySet()) {
+ final PyResolveContext resolveContext = PyResolveContext.noImplicits();
+ final PyCallExpression.PyArgumentsMapping mapping = ((PyCallExpression)callExpression).mapArguments(resolveContext);
+ for (Map.Entry parameterEntry : mapping.getMappedParameters().entrySet()) {
if (parameterEntry.getValue().equals(element)) {
parameterEntry.getKey().delete();
}
diff --git a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
index 6d501d44cc3c..32aa224bbbd2 100644
--- a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java
@@ -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 map(@NotNull PyCallExpression callExpression,
- @NotNull PyResolveContext resolveContext) {
- return map(callExpression, 0, resolveContext);
- }
-
- @NotNull
- public static Map map(@NotNull PyCallExpression callExpression,
- int implicitArgumentOffset,
- @NotNull PyResolveContext resolveContext) {
- final Map results = new LinkedHashMap();
- 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 allParameters = PyUtil.getParameters(markedCallee.getCallable(), context);
- final List parameters = dropImplicitParameters(allParameters, markedCallee.getImplicitOffset());
- final List arguments = Arrays.asList(argumentList.getArguments());
-
- final List positionalArguments = filterPositionalArguments(arguments);
- final List keywordArguments = filterKeywordArguments(arguments);
- final List variadicPositionalArguments = filterVariadicPositionalArguments(arguments);
- final List variadicKeywordArguments = filterVariadicKeywordArguments(arguments);
-
- boolean seenSingleStar = false;
- final List unmappedParameters = new ArrayList();
- 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 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 filterPositionalArguments(@NotNull List arguments) {
- final List results = new ArrayList();
- for (PyExpression argument : arguments) {
- if (isPositionalArg(argument)) {
- results.add(argument);
- }
- }
- return results;
- }
-
- @NotNull
- private static List filterKeywordArguments(@NotNull List arguments) {
- final List results = new ArrayList();
- for (PyExpression argument : arguments) {
- if (argument instanceof PyKeywordArgument) {
- results.add((PyKeywordArgument)argument);
- }
- }
- return results;
- }
-
- @NotNull
- private static List filterVariadicPositionalArguments(@NotNull List arguments) {
- final List results = new ArrayList();
- for (PyExpression argument : arguments) {
- if (argument != null && isVariadicPositionalArgument(argument)) {
- results.add(argument);
- }
- }
- return results;
- }
-
- @NotNull
- private static List filterVariadicKeywordArguments(@NotNull List arguments) {
- final List results = new ArrayList();
- 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 next(@NotNull List list) {
- return list.isEmpty() ? null : list.remove(0);
- }
-
- @NotNull
- private static List dropImplicitParameters(@NotNull List parameters, int offset) {
- final ArrayList results = new ArrayList(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).
*/
diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
index f87e0bd99e7b..00c122c7d11d 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
@@ -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 mappedParameters = new LinkedHashMap();
+ final PyArgumentList argumentList = callExpression.getArgumentList();
+ final PyCallExpression.PyMarkedCallee markedCallee = callExpression.resolveCallee(resolveContext);
+ if (markedCallee != null && argumentList != null) {
+ final TypeEvalContext context = resolveContext.getTypeEvalContext();
+ final List allParameters = PyUtil.getParameters(markedCallee.getCallable(), context);
+ final List parameters = dropImplicitParameters(allParameters, markedCallee.getImplicitOffset());
+ final List arguments = Arrays.asList(argumentList.getArguments());
+
+ final List positionalArguments = filterPositionalArguments(arguments);
+ final List keywordArguments = filterKeywordArguments(arguments);
+ final List variadicPositionalArguments = filterVariadicPositionalArguments(arguments);
+ final List variadicKeywordArguments = filterVariadicKeywordArguments(arguments);
+
+ boolean seenSingleStar = false;
+ final List unmappedParameters = new ArrayList();
+ 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 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 filterPositionalArguments(@NotNull List arguments) {
+ final List results = new ArrayList();
+ for (PyExpression argument : arguments) {
+ if (isPositionalArgument(argument)) {
+ results.add(argument);
+ }
+ }
+ return results;
+ }
+
+ @NotNull
+ private static List filterKeywordArguments(@NotNull List arguments) {
+ final List results = new ArrayList();
+ for (PyExpression argument : arguments) {
+ if (argument instanceof PyKeywordArgument) {
+ results.add((PyKeywordArgument)argument);
+ }
+ }
+ return results;
+ }
+
+ @NotNull
+ private static List filterVariadicPositionalArguments(@NotNull List arguments) {
+ final List results = new ArrayList();
+ for (PyExpression argument : arguments) {
+ if (argument != null && isVariadicPositionalArgument(argument)) {
+ results.add(argument);
+ }
+ }
+ return results;
+ }
+
+ @NotNull
+ private static List filterVariadicKeywordArguments(@NotNull List arguments) {
+ final List results = new ArrayList();
+ 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 next(@NotNull List list) {
+ return list.isEmpty() ? null : list.remove(0);
+ }
+
+ @NotNull
+ private static List dropImplicitParameters(@NotNull List parameters, int offset) {
+ final ArrayList results = new ArrayList(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);
+ }
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java
index 722b769da580..f2011b372ddb 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java
@@ -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);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
index 6aba3ea3658b..73cf915e0202 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
@@ -157,6 +157,12 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase 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);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
index d38c5060fab4..2c541faafecc 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java
@@ -269,8 +269,8 @@ public class PyNamedParameterImpl extends PyBaseElementImpl mapping = CallArgumentsMappingImpl.map(call, resolveContext);
- for (Map.Entry entry : mapping.entrySet()) {
+ final PyCallExpression.PyArgumentsMapping mapping = call.mapArguments(resolveContext);
+ for (Map.Entry 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 mapping = CallArgumentsMappingImpl.map(callExpression, resolveContext);
- for (Map.Entry entry : mapping.entrySet()) {
+ final PyCallExpression.PyArgumentsMapping mapping = callExpression.mapArguments(resolveContext);
+ for (Map.Entry entry : mapping.getMappedParameters().entrySet()) {
if (entry.getKey() == element) {
return entry.getValue();
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
index 0adb036bb99c..d4edb85a0180 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
@@ -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 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());
}
}
}
diff --git a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
index 2bbdc109f59d..c370343e0ee4 100644
--- a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
+++ b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java
@@ -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 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());
}