Merge remote branch 'origin/master'

Conflicts:
	python/ideSrc/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
This commit is contained in:
Ekaterina Tuzova
2012-03-21 16:04:45 +04:00
25 changed files with 274 additions and 220 deletions
+2 -2
View File
@@ -15,13 +15,13 @@ def error(message, retcode):
sys.exit(retcode)
def error_no_pip():
error("Python package management tool 'pip' not found. Please install 'pip'", ERROR_NO_PACKAGING_TOOLS)
error("Python package management tool 'pip' not found. Please install 'pip' manually", ERROR_NO_PACKAGING_TOOLS)
def do_list():
try:
import pkg_resources
except ImportError:
error("Python package management tools not found. Please install 'setuptools' or 'distribute'", ERROR_NO_PACKAGING_TOOLS)
error("Python package management tools not found. Please install 'setuptools' or 'distribute' manually", ERROR_NO_PACKAGING_TOOLS)
for pkg in pkg_resources.working_set:
print('\t'.join([pkg.project_name, pkg.version, pkg.location]))
@@ -110,9 +110,8 @@ public class PyParameterInfoHandler implements ParameterInfoHandler<PyArgumentLi
// really we need to redo analysis every UI update; findElementForParameterInfo isn't called while typing
CallArgumentsMapping result = arglist.analyzeCall(PyResolveContext.noImplicits());
PyMarkedCallee marked = result.getMarkedCallee();
assert marked != null : "findElementForParameterInfo() did it wrong!";
if (marked == null) return; // resolution failed
final Callable callable = marked.getCallable();
if (callable == null) return; // resolution failed
final List<PyParameter> raw_params = Arrays.asList(callable.getParameterList().getParameters());
final List<PyNamedParameter> n_param_list = new ArrayList<PyNamedParameter>(raw_params.size());
@@ -12,6 +12,7 @@ import com.intellij.psi.impl.PsiTreeChangeEventImpl;
import com.intellij.psi.impl.PsiTreeChangePreprocessor;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import org.jetbrains.annotations.NotNull;
/**
* @author yole
@@ -30,7 +31,7 @@ public class PythonPsiManager extends AbstractProjectComponent implements PsiTre
myPsiManager.addTreeChangePreprocessor(this);
}
public void treeChanged(PsiTreeChangeEventImpl event) {
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
if (!(event.getFile() instanceof PyFile)) return;
boolean changedInsideCodeBlock = false;
@@ -36,8 +36,8 @@ public class PythonTokenSetContributor implements PythonDialectsTokenSetContribu
return TokenSet.create(PyElementTypes.STAR_IMPORT_ELEMENT, PyElementTypes.IMPORT_ELEMENT, PyElementTypes.CLASS_DECLARATION,
PyElementTypes.GLOBAL_STATEMENT, PyElementTypes.GENERATOR_EXPRESSION, PyElementTypes.DICT_COMP_EXPRESSION,
PyElementTypes.LIST_COMP_EXPRESSION, PyElementTypes.SET_COMP_EXPRESSION, PyElementTypes.WITH_STATEMENT,
PyElementTypes.FUNCTION_DECLARATION, PyElementTypes.ASSIGNMENT_STATEMENT, PyElementTypes.PARAMETER_LIST,
PyElementTypes.EXCEPT_PART, PyElementTypes.FOR_STATEMENT,
PyElementTypes.FUNCTION_DECLARATION, PyElementTypes.ASSIGNMENT_STATEMENT, PyElementTypes.EXCEPT_PART,
PyElementTypes.FOR_STATEMENT,
PyElementTypes.FROM_IMPORT_STATEMENT);
}
@@ -1832,6 +1832,9 @@ io.open.2 = \
:type mode: bytes \n\
:rtype: io.FileIO \n\
io.TextIOWrapper.__enter__ = \
:rtype: io.TextIOWrapper \n\
io.TextIOWrapper.read = \
:rtype: unicode \n\
@@ -1848,6 +1851,9 @@ io.TextIOWrapper.write = \
:type s: string \n\
:rtype: int \n\
io.FileIO.__enter__ = \
:rtype: io.FileIO \n\
io.FileIO.read = \
:rtype: bytes \n\
@@ -3,311 +3,392 @@
## 4.6. Sequence types
builtins.bytes.capitalize = \
__builtin__.bytes.__init__ = \
:rtype: bytes \n\
builtins.bytes.center = \
__builtin__.bytes.__add__ = \
:type y: bytes \n\
:rtype: bytes \n\
__builtin__.bytes.__mul__ = \
:type n: int or long \n\
:rtype: bytes \n\
__builtin__.bytes.__mod__ = \
:type y: object \n\
:rtype: bytes \n\
__builtin__.bytes.__rmul__ = \
:type n: int or long \n\
:rtype: bytes \n\
__builtin__.bytes.__rmod__ = \
:type y: object \n\
:rtype: bytes \n\
__builtin__.bytes.__getitem__ = \
:type y: int \n\
:rtype: bytes \n\
__builtin__.bytes.capitalize = \
:rtype: bytes \n\
__builtin__.bytes.center = \
:type width: int or long \n\
:type fillchar: bytes or None \n\
:rtype: bytes \n\
builtins.bytes.count = \
__builtin__.bytes.count = \
:type sub: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.bytes.decode = \
__builtin__.bytes.decode = \
:type encoding: str \n\
:type errors: str or None \n\
:rtype: str \n\
builtins.bytes.encode = \
__builtin__.bytes.encode = \
:type encoding: str \n\
:type errors: str or None \n\
:rtype: bytes \n\
builtins.bytes.endswith = \
__builtin__.bytes.endswith = \
:type suffix: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: bool \n\
builtins.bytes.find = \
__builtin__.bytes.find = \
:type sub: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.bytes.index = \
__builtin__.bytes.index = \
:type sub: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.bytes.isalnum = \
__builtin__.bytes.isalnum = \
:rtype: bool \n\
builtins.bytes.isalpha = \
__builtin__.bytes.isalpha = \
:rtype: bool \n\
builtins.bytes.isdigit = \
__builtin__.bytes.isdigit = \
:rtype: bool \n\
builtins.bytes.islower = \
__builtin__.bytes.islower = \
:rtype: bool \n\
builtins.bytes.isspace = \
__builtin__.bytes.isspace = \
:rtype: bool \n\
builtins.bytes.istitle = \
__builtin__.bytes.istitle = \
:rtype: bool \n\
builtins.bytes.isupper = \
__builtin__.bytes.isupper = \
:rtype: bool \n\
builtins.bytes.join = \
:type iterable: object \n\
__builtin__.bytes.join = \
:type iterable: collections.Iterable of bytes \n\
:rtype: bytes \n\
builtins.bytes.ljust = \
__builtin__.bytes.ljust = \
:type width: int or long \n\
:type fillchar: bytes or None \n\
:rtype: bytes \n\
builtins.bytes.lower = \
__builtin__.bytes.lower = \
:rtype: bytes \n\
builtins.bytes.lstrip = \
__builtin__.bytes.lstrip = \
:type chars: bytes or None \n\
:rtype: bytes \n\
builtins.bytes.partition = \
__builtin__.bytes.partition = \
:type sep: bytes \n\
:rtype: (bytes, bytes, bytes) \n\
builtins.bytes.replace = \
__builtin__.bytes.replace = \
:type old: bytes \n\
:type new: bytes \n\
:type count: int or long \n\
:rtype: bytes \n\
builtins.bytes.rfind = \
__builtin__.bytes.rfind = \
:type sub: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.bytes.rindex = \
__builtin__.bytes.rindex = \
:type sub: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.bytes.rpartition = \
__builtin__.bytes.rpartition = \
:type sep: bytes \n\
:rtype: (bytes, bytes, bytes) \n\
builtins.bytes.rsplit = \
__builtin__.bytes.rsplit = \
:type sep: bytes or None \n\
:type maxsplit: int or long or None \n\
:rtype: list of bytes \n\
builtins.bytes.rstrip = \
__builtin__.bytes.rstrip = \
:type chars: bytes or None \n\
:rtype: bytes \n\
builtins.bytes.split = \
__builtin__.bytes.split = \
:type sep: bytes or None \n\
:type maxsplit: int or long or None \n\
:rtype: list of bytes \n\
builtins.bytes.splitlines = \
__builtin__.bytes.splitlines = \
:type keepends: bool or int or long or None \n\
:rtype: list of bytes \n\
builtins.bytes.startswith = \
__builtin__.bytes.startswith = \
:type prefix: bytes \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: bool \n\
builtins.bytes.strip = \
__builtin__.bytes.strip = \
:type chars: bytes or None \n\
:rtype: bytes \n\
builtins.bytes.swapcase = \
__builtin__.bytes.swapcase = \
:rtype: bytes \n\
builtins.bytes.title = \
__builtin__.bytes.title = \
:rtype: bytes \n\
builtins.bytes.translate = \
__builtin__.bytes.translate = \
:type table: object \n\
:type deletechars: bytes \n\
:rtype: bytes \n\
builtins.bytes.upper = \
__builtin__.bytes.upper = \
:rtype: bytes \n\
builtins.bytes.zfill = \
__builtin__.bytes.zfill = \
:type width: int or long \n\
:rtype: bytes \n\
builtins.str.capitalize = \
__builtin__.str.__init__ = \
:rtype: str \n\
builtins.str.center = \
__builtin__.str.__add__ = \
:type y: str \n\
:rtype: str \n\
__builtin__.str.__mul__ = \
:type n: int or long \n\
:rtype: str \n\
__builtin__.str.__mod__ = \
:type y: object \n\
:rtype: str \n\
__builtin__.str.__rmul__ = \
:type n: int or long \n\
:rtype: str \n\
__builtin__.str.__rmod__ = \
:type y: object \n\
:rtype: str \n\
__builtin__.str.__getitem__ = \
:type y: int \n\
:rtype: str \n\
__builtin__.str.capitalize = \
:rtype: str \n\
__builtin__.str.center = \
:type width: int or long \n\
:type fillchar: str or None \n\
:rtype: str \n\
builtins.str.count = \
__builtin__.str.count = \
:type sub: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.str.decode = \
__builtin__.str.decode = \
:type encoding: str \n\
:type errors: str or None \n\
:rtype: str \n\
builtins.str.encode = \
__builtin__.str.encode = \
:type encoding: str \n\
:type errors: str or None \n\
:rtype: bytes \n\
builtins.str.endswith = \
__builtin__.str.endswith = \
:type suffix: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: bool \n\
builtins.str.find = \
__builtin__.str.find = \
:type sub: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.str.index = \
__builtin__.str.index = \
:type sub: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.str.isalnum = \
__builtin__.str.isalnum = \
:rtype: bool \n\
builtins.str.isalpha = \
__builtin__.str.isalpha = \
:rtype: bool \n\
builtins.str.isdecimal = \
__builtin__.str.isdecimal = \
:rtype: bool \n\
builtins.str.isdigit = \
__builtin__.str.isdigit = \
:rtype: bool \n\
builtins.str.islower = \
__builtin__.str.islower = \
:rtype: bool \n\
builtins.str.isnumeric = \
__builtin__.str.isnumeric = \
:rtype: bool \n\
builtins.str.isspace = \
__builtin__.str.isspace = \
:rtype: bool \n\
builtins.str.istitle = \
__builtin__.str.istitle = \
:rtype: bool \n\
builtins.str.isupper = \
__builtin__.str.isupper = \
:rtype: bool \n\
builtins.str.join = \
:type iterable: object \n\
__builtin__.str.join = \
:type iterable: collections.Iterable of str \n\
:rtype: str \n\
builtins.str.ljust = \
__builtin__.str.ljust = \
:type width: int or long \n\
:type fillchar: str or None \n\
:rtype: str \n\
builtins.str.lower = \
__builtin__.str.lower = \
:rtype: str \n\
builtins.str.lstrip = \
__builtin__.str.lstrip = \
:type chars: str or None \n\
:rtype: str \n\
builtins.str.partition = \
__builtin__.str.partition = \
:type sep: str \n\
:rtype: (str, str, str) \n\
builtins.str.replace = \
__builtin__.str.replace = \
:type old: str \n\
:type new: str \n\
:type count: int or long \n\
:rtype: str \n\
builtins.str.rfind = \
__builtin__.str.rfind = \
:type sub: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.str.rindex = \
__builtin__.str.rindex = \
:type sub: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: int or long \n\
builtins.str.rpartition = \
__builtin__.str.rpartition = \
:type sep: str \n\
:rtype: (str, str, str) \n\
builtins.str.rsplit = \
__builtin__.str.rsplit = \
:type sep: str or None \n\
:type maxsplit: int or long or None \n\
:rtype: list of str \n\
builtins.str.rstrip = \
__builtin__.str.rstrip = \
:type chars: str or None \n\
:rtype: str \n\
builtins.str.split = \
__builtin__.str.split = \
:type sep: str or None \n\
:type maxsplit: int or long or None \n\
:rtype: list of str \n\
builtins.str.splitlines = \
__builtin__.str.splitlines = \
:type keepends: bool or int or long or None \n\
:rtype: list of str \n\
builtins.str.startswith = \
__builtin__.str.startswith = \
:type prefix: str \n\
:type start: int or long or None \n\
:type end: int or long or None \n\
:rtype: bool \n\
builtins.str.strip = \
__builtin__.str.strip = \
:type chars: str or None \n\
:rtype: str \n\
builtins.str.swapcase = \
__builtin__.str.swapcase = \
:rtype: str \n\
builtins.str.title = \
__builtin__.str.title = \
:rtype: str \n\
builtins.str.translate = \
__builtin__.str.translate = \
:type table: object \n\
:type deletechars: str \n\
:rtype: str \n\
builtins.str.upper = \
__builtin__.str.upper = \
:rtype: str \n\
builtins.str.zfill = \
__builtin__.str.zfill = \
:type width: int or long \n\
:rtype: str \n\
## 15.2. io
io.IOBase.readlines = \
:rtype: list of bytes \n\
io.IOBase.writelines = \
:type lines: collections.Iterable of bytes \n\
io.IOBase.__iter__ = \
:rtype: list of bytes \n\
io.IOBase.next = \
:rtype: bytes \n\
io._IOBase.readlines = \
:rtype: list of bytes \n\
io._IOBase.writelines = \
:type lines: collections.Iterable of bytes \n\
io._IOBase.__iter__ = \
:rtype: list of bytes \n\
io._IOBase.next = \
:rtype: bytes \n\
@@ -46,7 +46,7 @@ public class DocStringParameterReference extends PsiReferenceBase<PsiElement> {
@Nullable
private PsiElement resolveParameter(PyFunction owner) {
return owner.getParameterList().getElementNamed(getCanonicalText());
return owner.getParameterList().findParameterByName(getCanonicalText());
}
@NotNull
@@ -490,11 +490,12 @@ class DocumentationBuilder {
private void addModulePath(PyFile followed) {
// what to prepend to a module description?
String path = VfsUtil.urlToPath(followed.getUrl());
if ("".equals(path)) {
final VirtualFile file = followed.getVirtualFile();
if (file == null) {
myProlog.addWith(TagSmall, $(PyBundle.message("QDOC.module.path.unknown")));
}
else {
final String path = file.getPath();
RootFinder finder = new RootFinder(path);
RootVisitorHost.visitRoots(followed, finder);
final String root_path = finder.getResult();
@@ -173,7 +173,9 @@ public class PyStringLiteralLexer extends LexerBase {
}
public int getTokenEnd() {
assert myStart < myEnd || (myStart == myEnd && myEnd == myBufferEnd);
if (!(myStart < myEnd || (myStart == myEnd && myEnd == myBufferEnd))) {
LOG.error("myStart=" + myStart + " myEnd="+ myEnd + " myBufferEnd=" + myBufferEnd + " text=" + myBuffer.subSequence(myStart, myBufferEnd));
}
return myEnd;
}
@@ -22,7 +22,9 @@ import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.jetbrains.python.PythonHelpersLocator;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyListLiteralExpression;
import com.jetbrains.python.psi.PyStringLiteralExpression;
import com.jetbrains.python.remote.PyRemoteInterpreterException;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import com.jetbrains.python.remote.PythonRemoteSdkAdditionalData;
@@ -31,6 +33,7 @@ import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.util.io.FileUtilRt;
import javax.swing.event.HyperlinkEvent;
import java.io.File;
@@ -206,7 +209,7 @@ public class PyPackageManager {
args.add("install");
final File buildDir;
try {
buildDir = FileUtil.createTempDirectory("packaging", null);
buildDir = FileUtilRt.createTempDirectory("packaging", null);
}
catch (IOException e) {
throw new PyExternalProcessException(ERROR_ACCESS_DENIED, PACKAGING_TOOL, args, "Cannot create temporary build directory");
@@ -257,16 +260,12 @@ public class PyPackageManager {
}
@Nullable
public PyPackage findPackage(String name) {
try {
for (PyPackage pkg : getPackages()) {
if (name.equals(pkg.getName())) {
return pkg;
}
public PyPackage findPackage(String name) throws PyExternalProcessException {
for (PyPackage pkg : getPackages()) {
if (name.equals(pkg.getName())) {
return pkg;
}
}
catch (PyExternalProcessException ignored) {
}
return null;
}
@@ -204,8 +204,13 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
}
if (builder.getTokenType() == PyTokenTypes.EQ) {
maybeExprMarker.rollbackTo();
final int rollbackOffset = builder.getCurrentOffset();
getExpressionParser().parseExpression(false, true);
LOG.assertTrue(builder.getTokenType() == PyTokenTypes.EQ);
final int offsetAfterExpr = builder.getCurrentOffset();
if (builder.getTokenType() != PyTokenTypes.EQ) {
LOG.error("'=' after rollback expected", builder.getTokenType() + "; " +
builder.getOriginalText().subSequence(rollbackOffset, offsetAfterExpr).toString());
}
builder.advanceLexer();
}
else {
@@ -95,7 +95,7 @@ public interface PyCallExpression extends PyExpression {
* Couples function with a flag describing the way it is called.
*/
class PyMarkedCallee {
Callable myCallable;
@NotNull final Callable myCallable;
PyFunction.Modifier myModifier;
int myImplicitOffset;
boolean myImplicitlyResolved;
@@ -104,7 +104,7 @@ public interface PyCallExpression extends PyExpression {
* Method-oriented constructor.
*
* @param function the method (or any other callable, but why bother then).
* @param flags result of decorators or wrapping.
* @param modifier classmethod or staticmethod modifier
* @param offset implicit argument offset; parameters up to this are implicitly filled in the call.
* @param implicitlyResolved value for {@link #isImplicitlyResolved()}
*/
@@ -115,13 +115,7 @@ public interface PyCallExpression extends PyExpression {
myImplicitlyResolved = implicitlyResolved;
}
public PyMarkedCallee(Callable callable, boolean implicitlyResolved) {
myCallable = callable;
myModifier = null;
myImplicitOffset = 0;
myImplicitlyResolved = implicitlyResolved;
}
@NotNull
public Callable getCallable() {
return myCallable;
}
@@ -2,7 +2,6 @@ package com.jetbrains.python.psi;
import com.intellij.psi.PsiFile;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -16,12 +15,6 @@ public interface PyFile extends PyElement, PsiFile, PyDocStringOwner, ScopeOwner
List<PyTargetExpression> getTopLevelAttributes();
/**
@return an URL of file, maybe bogus if virtual file is not present.
*/
@NotNull
String getUrl();
@Nullable
PyFunction findTopLevelFunction(String name);
@@ -44,7 +44,7 @@ public class PyFileElementType extends IStubFileElementType<PyFileStub> {
@Override
public int getStubVersion() {
return 41;
return 42;
}
@Nullable
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
* Represents function parameter list.
* Date: 29.05.2005
*/
public interface PyParameterList extends PyElement, StubBasedPsiElement<PyParameterListStub>, NameDefiner {
public interface PyParameterList extends PyElement, StubBasedPsiElement<PyParameterListStub> {
/**
* Extracts the individual parameters.
@@ -18,6 +18,10 @@ public interface PyParameterList extends PyElement, StubBasedPsiElement<PyParame
*/
PyParameter[] getParameters();
@Nullable
PyNamedParameter findParameterByName(@NotNull String name);
/**
* Adds a paramter to list, after all other parameters.
* @param param what to add
@@ -69,15 +69,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
return "PyFile:" + getName();
}
@NotNull
public String getUrl() {
String fname;
VirtualFile vfile = getVirtualFile();
if (vfile != null) fname = vfile.getUrl();
else fname = "(null)://" + this.toString();
return fname;
}
public PyFunction findTopLevelFunction(String name) {
return findByName(name, getTopLevelFunctions());
}
@@ -22,9 +22,13 @@ public class PyKeywordArgumentReference extends PsiReferenceBase.Poly<PyKeywordA
@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
final String keyword = myElement.getKeyword();
if (keyword == null) {
return ResolveResult.EMPTY_ARRAY;
}
PsiElement call = PsiTreeUtil.getParentOfType(myElement, PyCallExpression.class, PyClass.class);
if (!(call instanceof PyCallExpression)) {
return new ResolveResult[0];
return ResolveResult.EMPTY_ARRAY;
}
final PyExpression callee = ((PyCallExpression)call).getCallee();
if (callee == null) return ResolveResult.EMPTY_ARRAY;
@@ -38,7 +42,7 @@ public class PyKeywordArgumentReference extends PsiReferenceBase.Poly<PyKeywordA
if (element == null) continue;
final PyFunction calleeFunction = resolveToFunction(element, new HashSet<PsiElement>());
if (calleeFunction != null) {
final PsiElement result = calleeFunction.getParameterList().getElementNamed(myElement.getKeyword());
final PsiElement result = calleeFunction.getParameterList().findParameterByName(keyword);
if (result != null) {
resultList.add(new PsiElementResolveResult(result));
}
@@ -28,7 +28,12 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
@NotNull
public PyParameterList getParameterList() {
return childToPsiNotNull(PyElementTypes.PARAMETER_LIST_SET, 0);
final PyElement child = childToPsi(PyElementTypes.PARAMETER_LIST_SET, 0);
if (child == null) {
throw new RuntimeException("parameter list must not be null; text=" + getText());
}
//noinspection unchecked
return (PyParameterList)child;
}
@Nullable
@@ -1,6 +1,7 @@
package com.jetbrains.python.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.IStubElementType;
import com.jetbrains.python.PyElementTypes;
@@ -9,8 +10,6 @@ import com.jetbrains.python.psi.stubs.PyParameterListStub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
/**
* @author yole
*/
@@ -152,17 +151,19 @@ public class PyParameterListImpl extends PyBaseElementImpl<PyParameterListStub>
//return false;
}
@NotNull
public Iterable<PyElement> iterateNames() {
return new ArrayList<PyElement>(ParamHelper.collectNamedParameters(this));
}
public PyElement getElementNamed(final String the_name) {
return IterHelper.findName(iterateNames(), the_name);
}
public boolean mustResolveOutside() {
return true;
@Override
@Nullable
public PyNamedParameter findParameterByName(@NotNull final String name) {
final Ref<PyNamedParameter> result = new Ref<PyNamedParameter>();
ParamHelper.walkDownParamArray(getParameters(), new ParamHelper.ParamVisitor() {
@Override
public void visitNamedParameter(PyNamedParameter param, boolean first, boolean last) {
if (name.equals(param.getName())) {
result.set(param);
}
}
});
return result.get();
}
public String getPresentableText(final boolean includeDefaultValue) {
@@ -283,15 +283,23 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
}
}
if (PyABCUtil.isSubclass(pyClass, PyNames.ITERATOR)) {
PyFunction next = pyClass.findMethodByName(PyNames.NEXT, true);
if (next == null) {
next = pyClass.findMethodByName(PyNames.DUNDER_NEXT, true);
final PyFunction iter = pyClass.findMethodByName(PyNames.ITER, true);
PyType iterMethodType = null;
if (iter != null) {
iterMethodType = getContextSensitiveType(iter, context, source);
}
if (next instanceof PyFunctionImpl) {
type = ((PyFunctionImpl)next).getReturnType(context, source, new HashMap<PyExpression, PyNamedParameter>());
if (iterMethodType instanceof PyCollectionType) {
final PyCollectionType collectionType = (PyCollectionType)iterMethodType;
type = collectionType.getElementType(context);
}
else if (next != null) {
type = next.getReturnType(context, null);
if (type == null) {
PyFunction next = pyClass.findMethodByName(PyNames.NEXT, true);
if (next == null) {
next = pyClass.findMethodByName(PyNames.DUNDER_NEXT, true);
}
if (next != null) {
type = getContextSensitiveType(next, context, source);
}
}
}
}
@@ -307,6 +315,15 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
return null;
}
@Nullable
private static PyType getContextSensitiveType(@NotNull PyFunction function, @NotNull TypeEvalContext context,
@NotNull PyExpression source) {
if (function instanceof PyFunctionImpl) {
return ((PyFunctionImpl)function).getReturnType(context, source, new HashMap<PyExpression, PyNamedParameter>());
}
return function.getReturnType(context, null);
}
@Nullable
private PyType getTypeFromExcept() {
PyExceptPart exceptPart = PsiTreeUtil.getParentOfType(this, PyExceptPart.class);
@@ -7,7 +7,6 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
@@ -20,7 +19,10 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.impl.PyReferenceExpressionImpl;
import com.jetbrains.python.psi.impl.ResolveResultList;
import com.jetbrains.python.psi.resolve.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.QualifiedNameResolver;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.resolve.ResolveImportUtil;
import com.jetbrains.python.psi.types.PyModuleType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
@@ -187,7 +189,6 @@ public class PyImportReference extends PyReferenceImpl {
public Object[] execute() {
int relative_level = -1;
Condition<PsiElement> node_filter = new PyResolveUtil.FilterNameNotIn(myNamesAlready);
InsertHandler<LookupElement> insertHandler = null;
// NOTE: could use getPointInImport()
@@ -51,4 +51,12 @@ public class PyParameterListElementType extends PyStubElementType<PyParameterLis
protected IStubElementType getStubElementType() {
return PyElementTypes.PARAMETER_LIST;
}
@Override
public boolean shouldCreateStub(ASTNode node) {
if (node.getTreeParent().getElementType() == PyElementTypes.LAMBDA_EXPRESSION) {
return false;
}
return super.shouldCreateStub(node);
}
}
@@ -24,7 +24,6 @@ import com.jetbrains.python.psi.impl.PyQualifiedName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -146,12 +145,10 @@ public class PyResolveUtil {
*
* @param processor a visitor that says when the crawl is done and collects info.
* @param elt element from which we start (not checked by processor); if null, the search immediately returns null.
* @param roof if not null, search continues only below the roof and including it.
* @param fromunder if true, begin search not above elt, but from a [possibly imaginary] node right below elt; so elt gets analyzed, too.
* @return first element that the processor accepted.
*/
@Nullable
public static PsiElement treeCrawlUp(PsiScopeProcessor processor, boolean fromunder, PsiElement elt, @Nullable PsiElement roof) {
public static PsiElement treeCrawlUp(PsiScopeProcessor processor, PsiElement elt) {
if (elt == null || !elt.isValid()) return null; // can't find anyway.
PsiElement seeker = elt;
PsiElement cap = PyUtil.getConcealingParent(elt);
@@ -159,13 +156,7 @@ public class PyResolveUtil {
final boolean is_outside_param_list = PsiTreeUtil.getParentOfType(elt, PyParameterList.class) == null;
do {
ProgressManager.checkCanceled();
if (fromunder) {
fromunder = false; // only honour fromunder once per call
seeker = getPrevNodeOf(PsiTreeUtil.getDeepestLast(seeker), processor);
}
else { // main case
seeker = getPrevNodeOf(seeker, processor);
}
seeker = getPrevNodeOf(seeker, processor);
// aren't we in the same defining assignment, global, etc?
if ((seeker instanceof NameDefiner) && ((NameDefiner)seeker).mustResolveOutside() && PsiTreeUtil.isAncestor(seeker, elt, true)) {
seeker = getPrevNodeOf(seeker, processor);
@@ -191,8 +182,6 @@ public class PyResolveUtil {
break;
} // seeker is contextually under elt already
}
// are we still under the roof?
if ((roof != null) && (seeker != null) && !PsiTreeUtil.isAncestor(roof, seeker, false)) return null;
// maybe we're capped by a class? param lists are not capped though syntactically inside the function.
if (is_outside_param_list && refersFromMethodToClass(capFunction, seeker)) continue;
// names defined in a comprehension element are only visible inside it or the list comp expressions directly above it
@@ -236,29 +225,6 @@ public class PyResolveUtil {
return false;
}
/**
* Crawls up the PSI tree, checking nodes as if crawling backwards through source lexemes.
*
* @param processor a visitor that says when the crawl is done and collects info.
* @param fromunder if true, search not above elt, but from a [possibly imaginary] node right below elt; so elt gets analyzed, too.
* @param elt element from which we start (not checked by processor); if null, the search immediately fails.
* @return first element that the processor accepted.
*/
@Nullable
public static PsiElement treeCrawlUp(PsiScopeProcessor processor, boolean fromunder, PsiElement elt) {
return treeCrawlUp(processor, fromunder, elt, null);
}
/**
* Returns treeCrawlUp(processor, elt, false). A convenience method.
*
* @see PyResolveUtil#treeCrawlUp(com.intellij.psi.scope.PsiScopeProcessor, boolean, com.intellij.psi.PsiElement)
*/
@Nullable
public static PsiElement treeCrawlUp(PsiScopeProcessor processor, PsiElement elt) {
return treeCrawlUp(processor, false, elt);
}
/**
* Unwinds a multi-level qualified expression into a path, as seen in source text, i.e. outermost qualifier first.
*
@@ -317,35 +283,4 @@ public class PyResolveUtil {
}
}
/**
* Accepts only names not contained in a given collection.
*/
public static class FilterNameNotIn implements Condition<PsiElement> {
private final Collection<String> myNames;
public FilterNameNotIn(Collection<String> names) {
myNames = names;
}
public boolean value(PsiElement target) {
if (target instanceof PsiNamedElement) {
return !myNames.contains(((PsiNamedElement)target).getName());
}
else if (target instanceof PyReferenceExpression) {
return !myNames.contains(((PyReferenceExpression)target).getReferencedName());
}
else if (target instanceof NameDefiner) {
NameDefiner definer = (NameDefiner)target;
for (PyElement expr : definer.iterateNames()) {
if (expr != null) {
String referencedName = expr.getName();
if (myNames.contains(referencedName)) return false;
}
}
}
return true; // nothing failed us
}
}
}
@@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.jetbrains.django.facet.DjangoFacetType;
import com.jetbrains.python.console.PydevConsoleRunner;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.sdk.PythonSdkType;
@@ -49,9 +50,14 @@ public class QualifiedNameResolver implements RootVisitor {
}
public QualifiedNameResolver fromElement(@NotNull PsiElement foothold) {
myFootholdFile = foothold.getContainingFile().getOriginalFile();
if (foothold instanceof PsiDirectory) {
myFootholdFile = (PsiFile)PyUtil.turnDirIntoInit(foothold);
}
else {
myFootholdFile = foothold.getContainingFile().getOriginalFile();
}
myPsiManager = foothold.getManager();
setModule(ModuleUtil.findModuleForPsiElement(myFootholdFile));
setModule(ModuleUtil.findModuleForPsiElement(foothold));
if (PydevConsoleRunner.isInPydevConsole(foothold)) {
withAllModules();
}
@@ -21,10 +21,11 @@ public class HighlightingAnnotator extends PyAnnotator {
@Override
public void visitPyReferenceExpression(PyReferenceExpression node) {
if (node.getQualifier() == null) {
final String referencedName = node.getReferencedName();
if (node.getQualifier() == null && referencedName != null) {
PyFunction function = PsiTreeUtil.getParentOfType(node, PyFunction.class);
if (function != null) {
final PyNamedParameter element = (PyNamedParameter) function.getParameterList().getElementNamed(node.getReferencedName());
final PyNamedParameter element = function.getParameterList().findParameterByName(referencedName);
if (element != null) {
Annotation annotation = getHolder().createInfoAnnotation(node, null);
annotation.setTextAttributes(isSelf(element, function) ? PyHighlighter.PY_SELF_PARAMETER : PyHighlighter.PY_PARAMETER);