Merge branch 'vlan/pyi'

This commit is contained in:
Andrey Vlasovskikh
2015-09-09 11:46:04 +03:00
89 changed files with 2545 additions and 1120 deletions
@@ -1,109 +0,0 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
/**
* Result of analysis of argument list application to the callee.
* Contains neatly arranged lists and mappings between arguments and parameters,
* including error diagnostics.
*/
public interface CallArgumentsMapping {
/**
* @return A mapping argument->parameter for non-starred parameters (but includes starred argument).
*/
@NotNull
Map<PyExpression, PyNamedParameter> getPlainMappedParams();
/**
* Consider a piece of Python 2.x code:
* <pre>
* def f(a, (b, c,), d):
* ...
*
* x = (1, 2)
* f(10, x, 20)
* </pre>
* Here, argument <tt>x</tt> successfully maps to both <tt>b</tt> and <tt>c</tt> parameters.
* This case is rare, so a separate method is introduced, to keep {@link CallArgumentsMapping#getPlainMappedParams()} simple.
* @return mapping of arguments to nested parameters that get collectively mapped to that argument.
*/
@NotNull Map<PyExpression, List<PyNamedParameter>> getNestedMappedParams();
/**
* @return First *arg, or null.
*/
@Nullable
PyStarArgument getTupleArg();
/**
* @return A list of parameters mapped to a *arg.
*/
@NotNull List<PyNamedParameter> getTupleMappedParams();
/**
* @return First **arg, or null.
*/
@Nullable
PyStarArgument getKwdArg();
/**
* @return A list of parameters mapped to an **arg.
*/
@NotNull List<PyNamedParameter> getKwdMappedParams();
/**
* @return A list of parameters for which no arguments were found ('missing').
*/
@NotNull
List<PyNamedParameter> getUnmappedParams();
/**
* @return Lists all args with their flags.
* @see com.jetbrains.python.psi.CallArgumentsMapping.ArgFlag
*/
Map<PyExpression, EnumSet<ArgFlag>> getArgumentFlags();
boolean hasProblems();
/**
* @return result of a resolveCallee() against the function call to which the parameter list belongs.
*/
@Nullable
PyCallExpression.PyMarkedCallee getMarkedCallee();
PyArgumentList getArgumentList();
/**
* Flags to mark analysis results for an argument.
* Theoretically can be used together, but currently only make sense as a single value per argument.
*/
enum ArgFlag {
/** duplicate plain */ IS_DUP,
/** unexpected */ IS_UNMAPPED,
/** duplicate **arg */ IS_DUP_KWD,
/** duplicate *arg */ IS_DUP_TUPLE,
/** positional past keyword */ IS_POS_PAST_KWD,
/** *param is too long */ IS_TOO_LONG,
}
}
@@ -17,7 +17,6 @@ package com.jetbrains.python.psi;
import com.intellij.lang.ASTNode;
import com.jetbrains.python.FunctionParameter;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,19 +62,6 @@ public interface PyArgumentList extends PyElement {
@Nullable
PyCallExpression getCallExpression();
/**
* Tries to map the argument list to callee's idea of parameters.
*
* @param resolveContext the reference resolution context
* @param implicitOffset known from the context implicit offset
* @return a result object with mappings and diagnostic flags.
*/
@NotNull
CallArgumentsMapping analyzeCall(PyResolveContext resolveContext, int implicitOffset);
@NotNull
CallArgumentsMapping analyzeCall(PyResolveContext resolveContext);
@Nullable
ASTNode getClosingParen();
@@ -22,6 +22,9 @@ import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
/**
* Represents an entire call expression, like <tt>foo()</tt> or <tt>foo.bar[1]('x')</tt>.
*/
@@ -81,7 +84,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
PyExpression getKeywordArgument(String keyword);
/**
* TODO: Copy/Paste with {@link com.jetbrains.python.psi.PyArgumentList#addArgument(PyExpression)}
* TODO: Copy/Paste with {@link PyArgumentList#addArgument(PyExpression)}
* @param expression
*/
void addArgument(PyExpression expression);
@@ -114,6 +117,12 @@ public interface PyCallExpression extends PyCallSiteExpression {
@Nullable
PyMarkedCallee resolveCallee(PyResolveContext resolveContext, int implicitOffset);
@NotNull
PyArgumentsMapping mapArguments(@NotNull PyResolveContext resolveContext);
@NotNull
PyArgumentsMapping mapArguments(@NotNull PyResolveContext resolveContext, int implicitOffset);
/**
* Checks if the unqualified name of the callee matches any of the specified names
*
@@ -122,7 +131,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 +139,75 @@ public interface PyCallExpression extends PyCallSiteExpression {
*/
boolean isCallee(@NotNull FQNamesProvider... name);
class PyArgumentsMapping {
@NotNull private final PyCallExpression myCallExpression;
@Nullable private final PyMarkedCallee myCallee;
@NotNull private final Map<PyExpression, PyNamedParameter> myMappedParameters;
@NotNull private final List<PyParameter> myUnmappedParameters;
@NotNull private final List<PyExpression> myUnmappedArguments;
@NotNull private final List<PyNamedParameter> myParametersMappedToVariadicPositionalArguments;
@NotNull private final List<PyNamedParameter> myParametersMappedToVariadicKeywordArguments;
@NotNull private final Map<PyExpression, PyTupleParameter> myMappedTupleParameters;
public PyArgumentsMapping(@NotNull PyCallExpression expression,
@Nullable PyMarkedCallee markedCallee,
@NotNull Map<PyExpression, PyNamedParameter> mappedParameters,
@NotNull List<PyParameter> unmappedParameters,
@NotNull List<PyExpression> unmappedArguments,
@NotNull List<PyNamedParameter> parametersMappedToVariadicPositionalArguments,
@NotNull List<PyNamedParameter> parametersMappedToVariadicKeywordArguments,
@NotNull Map<PyExpression, PyTupleParameter> tupleMappedParameters) {
myCallExpression = expression;
myCallee = markedCallee;
myMappedParameters = mappedParameters;
myUnmappedParameters = unmappedParameters;
myUnmappedArguments = unmappedArguments;
myParametersMappedToVariadicPositionalArguments = parametersMappedToVariadicPositionalArguments;
myParametersMappedToVariadicKeywordArguments = parametersMappedToVariadicKeywordArguments;
myMappedTupleParameters = tupleMappedParameters;
}
@NotNull
public PyCallExpression getCallExpression() {
return myCallExpression;
}
@Nullable
public PyMarkedCallee getMarkedCallee() {
return myCallee;
}
@NotNull
public Map<PyExpression, PyNamedParameter> getMappedParameters() {
return myMappedParameters;
}
@NotNull
public List<PyParameter> getUnmappedParameters() {
return myUnmappedParameters;
}
@NotNull
public List<PyExpression> getUnmappedArguments() {
return myUnmappedArguments;
}
@NotNull
public List<PyNamedParameter> getParametersMappedToVariadicPositionalArguments() {
return myParametersMappedToVariadicPositionalArguments;
}
@NotNull
public List<PyNamedParameter> getParametersMappedToVariadicKeywordArguments() {
return myParametersMappedToVariadicKeywordArguments;
}
@NotNull
public Map<PyExpression, PyTupleParameter> getMappedTupleParameters() {
return myMappedTupleParameters;
}
}
/**
* Couples function with a flag describing the way it is called.
*/