PY-24990 Use the mapping of cls/self to receiver only to infer the call type

It doesn't affect the rest of the code insight that drastically.
This commit is contained in:
Mikhail Golubev
2017-12-15 15:14:12 +03:00
parent b25fc9d6c9
commit f44abaa895
3 changed files with 45 additions and 16 deletions
@@ -374,6 +374,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
class PyArgumentsMapping {
@NotNull private final PyCallSiteExpression myCallSiteExpression;
@Nullable private final PyMarkedCallee myMarkedCallee;
@NotNull private final List<PyCallableParameter> myImplicitParameters;
@NotNull private final Map<PyExpression, PyCallableParameter> myMappedParameters;
@NotNull private final List<PyCallableParameter> myUnmappedParameters;
@NotNull private final List<PyExpression> myUnmappedArguments;
@@ -383,6 +384,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
public PyArgumentsMapping(@NotNull PyCallSiteExpression callSiteExpression,
@Nullable PyMarkedCallee markedCallee,
@NotNull List<PyCallableParameter> implicitParameters,
@NotNull Map<PyExpression, PyCallableParameter> mappedParameters,
@NotNull List<PyCallableParameter> unmappedParameters,
@NotNull List<PyExpression> unmappedArguments,
@@ -391,6 +393,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
@NotNull Map<PyExpression, PyCallableParameter> tupleMappedParameters) {
myCallSiteExpression = callSiteExpression;
myMarkedCallee = markedCallee;
myImplicitParameters = implicitParameters;
myMappedParameters = mappedParameters;
myUnmappedParameters = unmappedParameters;
myUnmappedArguments = unmappedArguments;
@@ -399,10 +402,29 @@ public interface PyCallExpression extends PyCallSiteExpression {
myMappedTupleParameters = tupleMappedParameters;
}
/**
* @deprecated
* Use {@link #PyArgumentsMapping(PyCallSiteExpression, PyMarkedCallee, List, Map, List, List, List, List, Map)} that includes
* implicitly mapped parameters. This constructor will be removed in 2018.2.
*/
@Deprecated
public PyArgumentsMapping(@NotNull PyCallSiteExpression callSiteExpression,
@Nullable PyMarkedCallee markedCallee,
@NotNull Map<PyExpression, PyCallableParameter> mappedParameters,
@NotNull List<PyCallableParameter> unmappedParameters,
@NotNull List<PyExpression> unmappedArguments,
@NotNull List<PyCallableParameter> parametersMappedToVariadicPositionalArguments,
@NotNull List<PyCallableParameter> parametersMappedToVariadicKeywordArguments,
@NotNull Map<PyExpression, PyCallableParameter> tupleMappedParameters) {
this(callSiteExpression, markedCallee, Collections.emptyList(), mappedParameters, unmappedParameters, unmappedArguments,
parametersMappedToVariadicPositionalArguments, parametersMappedToVariadicKeywordArguments, tupleMappedParameters);
}
@NotNull
public static PyArgumentsMapping empty(@NotNull PyCallSiteExpression callSiteExpression) {
return new PyCallExpression.PyArgumentsMapping(callSiteExpression,
null,
Collections.emptyList(),
Collections.emptyMap(),
Collections.emptyList(),
Collections.emptyList(),
@@ -421,6 +443,11 @@ public interface PyCallExpression extends PyCallSiteExpression {
return myMarkedCallee;
}
@NotNull
public List<PyCallableParameter> getImplicitParameters() {
return myImplicitParameters;
}
@NotNull
public Map<PyExpression, PyCallableParameter> getMappedParameters() {
return myMappedParameters;
@@ -724,12 +724,15 @@ public class PyCallExpressionHelper {
final List<PyCallableParameter> parameters = markedCallee.getCallableType().getParameters(context);
if (parameters == null) return PyCallExpression.PyArgumentsMapping.empty(callExpression);
final List<PyCallableParameter> explicitParameters = dropImplicitParameters(parameters, markedCallee.getImplicitOffset());
final int safeImplicitOffset = Math.min(markedCallee.getImplicitOffset(), parameters.size());
final List<PyCallableParameter> explicitParameters = parameters.subList(safeImplicitOffset, parameters.size());
final List<PyCallableParameter> implicitParameters = parameters.subList(0, safeImplicitOffset);
final List<PyExpression> arguments = Arrays.asList(argumentList.getArguments());
final ArgumentMappingResults mappingResults = analyzeArguments(arguments, explicitParameters);
return new PyCallExpression.PyArgumentsMapping(callExpression,
markedCallee,
implicitParameters,
mappingResults.getMappedParameters(),
mappingResults.getUnmappedParameters(),
mappingResults.getUnmappedArguments(),
@@ -798,26 +801,18 @@ public class PyCallExpressionHelper {
if (parameters == null) return PyCallExpression.PyArgumentsMapping.empty(callSite);
final List<PyExpression> arguments = callSite.getArguments(callable);
final List<PyCallableParameter> explicitParameters =
filterExplicitParameters(parameters, callable, callSite, resolveContext);
final List<PyCallableParameter> explicitParameters = filterExplicitParameters(parameters, callable, callSite, resolveContext);
final List<PyCallableParameter> implicitParameters = parameters.subList(0, parameters.size() - explicitParameters.size());
final ArgumentMappingResults mappingResults = analyzeArguments(arguments, explicitParameters);
final Map<PyExpression, PyCallableParameter> mapped = new LinkedHashMap<>();
final PyExpression receiver = callSite.getReceiver(callable);
if (receiver != null && !explicitParameters.equals(parameters)) {
final PyCallableParameter first = ContainerUtil.getFirstItem(parameters);
if (first != null && first.getParameter() != null && first.getParameter().isSelf()) {
mapped.put(receiver, first);
}
}
mapped.putAll(mappingResults.getMappedParameters());
final PyCallExpression.PyMarkedCallee markedCallee =
new PyCallExpression.PyMarkedCallee(callableType, callable, null, 0, false, RatedResolveResult.RATE_NORMAL);
return new PyCallExpression.PyArgumentsMapping(callSite,
markedCallee,
mapped,
implicitParameters,
mappingResults.getMappedParameters(),
mappingResults.getUnmappedParameters(),
mappingResults.getUnmappedArguments(),
mappingResults.getParametersMappedToVariadicPositionalArguments(),
@@ -230,10 +230,17 @@ public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements
}
final PyExpression receiver = callSite.getReceiver(this);
final Map<PyExpression, PyCallableParameter> mapping =
PyCallExpressionHelper.mapArguments(callSite, this, context).getMappedParameters();
final PyCallExpression.PyArgumentsMapping fullMapping = PyCallExpressionHelper.mapArguments(callSite, this, context);
final Map<PyExpression, PyCallableParameter> mappedExplicitParameters = fullMapping.getMappedParameters();
return getCallType(receiver, mapping, context);
final Map<PyExpression, PyCallableParameter> allMappedParameters = new LinkedHashMap<>();
final PyCallableParameter firstImplicit = ContainerUtil.getFirstItem(fullMapping.getImplicitParameters());
if (receiver != null && firstImplicit != null) {
allMappedParameters.put(receiver, firstImplicit);
}
allMappedParameters.putAll(mappedExplicitParameters);
return getCallType(receiver, allMappedParameters, context);
}
@Nullable