diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py
index 94a679e4d12b..aa7439f9372f 100644
--- a/python/helpers/pydev/pydevd_vars.py
+++ b/python/helpers/pydev/pydevd_vars.py
@@ -183,8 +183,6 @@ def varToXML(val, name, doTrim=True):
except:
value = 'Unable to get repr for %s' % v.__class__
- print(name)
- print(quote(name))
xml = '_= ')), makeValidXmlValue(typeName))
if value:
@@ -208,9 +206,6 @@ def varToXML(val, name, doTrim=True):
else:
xmlValue = ''
- print(value)
- print(xmlValue)
-
if is_exception_on_eval:
xmlCont = ' isErrorOnEval="True"'
else:
diff --git a/python/resources/idea/PythonApplicationInfo.xml b/python/resources/idea/PythonApplicationInfo.xml
index 650c43cfad4b..adcc754cbabd 100644
--- a/python/resources/idea/PythonApplicationInfo.xml
+++ b/python/resources/idea/PythonApplicationInfo.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
index 3e8937006fa1..ce3b41999065 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java
@@ -50,7 +50,7 @@ public class PyDunderAllReference extends PsiReferenceBase dunderAll = containingFile.getDunderAll();
containingFile.processDeclarations(new PsiScopeProcessor() {
@Override
- public boolean execute(PsiElement element, ResolveState state) {
+ public boolean execute(@NotNull PsiElement element, ResolveState state) {
if (element instanceof PsiNamedElement && !(element instanceof LightNamedElement)) {
final String name = ((PsiNamedElement)element).getName();
if (name != null && PyUtil.getInitialUnderscores(name) == 0 && (dunderAll == null || !dunderAll.contains(name))) {
@@ -67,7 +67,7 @@ public class PyDunderAllReference extends PsiReferenceBase T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/codeInsight/PyGotoSuperHandler.java b/python/src/com/jetbrains/python/codeInsight/PyGotoSuperHandler.java
index b36b44fae95f..02575d3d477e 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyGotoSuperHandler.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyGotoSuperHandler.java
@@ -51,7 +51,7 @@ public class PyGotoSuperHandler implements CodeInsightActionHandler {
superClasses.get(0).navigate(true);
}
else {
- NavigationUtil.getPsiElementPopup(superClasses.toArray(new PyClass[superClasses.size()]), CodeInsightBundle.message("goto.super.class.chooser.title"))
+ NavigationUtil.getPsiElementPopup(superClasses.toArray(new PyClass[superClasses.size()]), "Choose superclass")
.showInBestPositionFor(editor);
}
}
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
index 05b5f9715aa0..c9559e7923a4 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
@@ -5,7 +5,6 @@ import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.patterns.StandardPatterns;
@@ -317,16 +316,6 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
private static final FilterPattern PY3K = new FilterPattern(new Py3kFilter());
- /**
- * Tail type that adds a space and a colon and puts cursor before colon. Used in things like "if".
- */
- public static final TailType PRE_COLON = new TailType() {
- public int processTail(Editor editor, int tailOffset) {
- tailOffset = insertChar(editor, insertChar(editor, tailOffset, ' '), ':');
- return moveCaret(editor, tailOffset, -1); // stand before ":"
- }
- };
-
// ======
private static void putKeywords(final CompletionResultSet result, TailType tail, @NonNls @NotNull String... words) {
@@ -362,7 +351,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
protected void addCompletions(
@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result
) {
- putKeywords(result, PRE_COLON, "def", "class", "for", "if", "while", "with");
+ putKeywords(result, TailType.NONE, "def", "class", "for", "if", "while", "with");
putKeywords(result, TailType.CASE_COLON, "try");
}
}
@@ -456,7 +445,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
//.andNot(RIGHT_AFTER_COLON)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
,
- new PyKeywordCompletionProvider(PRE_COLON, UnindentingInsertHandler.INSTANCE, "elif"));
+ new PyKeywordCompletionProvider(TailType.NONE, UnindentingInsertHandler.INSTANCE, "elif"));
}
private void addWithinTry() {
@@ -472,7 +461,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
protected void addCompletions(
@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result
) {
- putKeyword("except", UnindentingInsertHandler.INSTANCE, PRE_COLON, result);
+ putKeyword("except", UnindentingInsertHandler.INSTANCE, TailType.NONE, result);
putKeyword("finally", UnindentingInsertHandler.INSTANCE, TailType.CASE_COLON, result);
}
}
diff --git a/python/src/com/jetbrains/python/documentation/DocumentationBuilder.java b/python/src/com/jetbrains/python/documentation/DocumentationBuilder.java
index 1bce5f1f9c99..3be27d7d0ad6 100644
--- a/python/src/com/jetbrains/python/documentation/DocumentationBuilder.java
+++ b/python/src/com/jetbrains/python/documentation/DocumentationBuilder.java
@@ -200,13 +200,19 @@ class DocumentationBuilder {
final String target_name = myElement.getText();
//prolog_cat.add(TagSmall.apply($("Assigned to ", element.getText(), BR)));
prolog_cat.addWith(TagSmall, $(PyBundle.message("QDOC.assigned.to.$0", target_name)).addItem(BR));
- return ((PyTargetExpression)myElement).findAssignedValue();
+ final PyExpression assignedValue = ((PyTargetExpression)myElement).findAssignedValue();
+ if (assignedValue instanceof PyReferenceExpression) {
+ final PsiElement resolved = resolveWithoutImplicits((PyReferenceExpression) assignedValue);
+ if (resolved != null) {
+ return resolved;
+ }
+ }
+ return assignedValue;
}
if (myElement instanceof PyReferenceExpression) {
//prolog_cat.add(TagSmall.apply($("Assigned to ", element.getText(), BR)));
prolog_cat.addWith(TagSmall, $(PyBundle.message("QDOC.assigned.to.$0", myElement.getText())).addItem(BR));
- final QualifiedResolveResult resolveResult = ((PyReferenceExpression)myElement).followAssignmentsChain(PyResolveContext.noImplicits());
- return resolveResult.isImplicit() ? null : resolveResult.getElement();
+ return resolveWithoutImplicits((PyReferenceExpression)myElement);
}
// it may be a call to a standard wrapper
if (myElement instanceof PyCallExpression) {
@@ -223,6 +229,11 @@ class DocumentationBuilder {
return myElement;
}
+ private static PsiElement resolveWithoutImplicits(final PyReferenceExpression element) {
+ final QualifiedResolveResult resolveResult = element.followAssignmentsChain(PyResolveContext.noImplicits());
+ return resolveResult.isImplicit() ? null : resolveResult.getElement();
+ }
+
private void addInheritedDocString(PyFunction fun, PyClass cls) {
boolean not_found = true;
String meth_name = fun.getName();
diff --git a/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java b/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
index 0336c9c7a968..c56dd4fe5b9d 100644
--- a/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
+++ b/python/src/com/jetbrains/python/packaging/ui/PyPackagesPanel.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.Messages;
+import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.table.JBTable;
import com.intellij.util.Consumer;
@@ -28,7 +29,6 @@ import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;
@@ -122,25 +122,26 @@ public class PyPackagesPanel extends JPanel {
}
});
- myPackagesTable.addMouseListener(new MouseAdapter() {
- public void mouseClicked(MouseEvent e) {
- if (e.getClickCount() == 2) {
- if (mySelectedSdk != null && myInstallButton.isEnabled()) {
- ManagePackagesDialog dialog = new ManagePackagesDialog(myProject, mySelectedSdk, PyPackagesPanel.this);
- Point p = e.getPoint();
- int row = myPackagesTable.rowAtPoint(p);
- int column = myPackagesTable.columnAtPoint(p);
- if (row >= 0 && column >= 0) {
- Object pyPackage = myPackagesTable.getValueAt(row, 0);
- if (pyPackage instanceof PyPackage) {
- dialog.setSelected(((PyPackage)pyPackage).getName());
- }
+ new DoubleClickListener() {
+ @Override
+ protected boolean onDoubleClick(MouseEvent e) {
+ if (mySelectedSdk != null && myInstallButton.isEnabled()) {
+ ManagePackagesDialog dialog = new ManagePackagesDialog(myProject, mySelectedSdk, PyPackagesPanel.this);
+ Point p = e.getPoint();
+ int row = myPackagesTable.rowAtPoint(p);
+ int column = myPackagesTable.columnAtPoint(p);
+ if (row >= 0 && column >= 0) {
+ Object pyPackage = myPackagesTable.getValueAt(row, 0);
+ if (pyPackage instanceof PyPackage) {
+ dialog.setSelected(((PyPackage)pyPackage).getName());
}
- dialog.show();
}
+ dialog.show();
+ return true;
}
+ return false;
}
- });
+ }.installOn(myPackagesTable);
myNotificationArea.addLinkHandler(INSTALL_DISTRIBUTE, new Runnable() {
@Override
diff --git a/python/src/com/jetbrains/python/psi/PyElementGenerator.java b/python/src/com/jetbrains/python/psi/PyElementGenerator.java
index 28e8521e947d..009acc249478 100644
--- a/python/src/com/jetbrains/python/psi/PyElementGenerator.java
+++ b/python/src/com/jetbrains/python/psi/PyElementGenerator.java
@@ -53,13 +53,14 @@ public abstract class PyElementGenerator {
public abstract PsiElement insertItemIntoList(PyElement list, @Nullable PyExpression afterThis, PyExpression toInsert)
throws IncorrectOperationException;
- @Nullable
+ @NotNull
public abstract PyCallExpression createCallExpression(final LanguageLevel langLevel, String functionName);
public abstract PyImportStatement createImportStatementFromText(String text);
public abstract PyImportElement createImportElement(String name);
+ @NotNull
public abstract T createFromText(LanguageLevel langLevel, Class aClass, final String text);
/**
@@ -71,7 +72,7 @@ public abstract class PyElementGenerator {
* @param path a sequence of numbers, each telling which child to select at current tree level; 0 means first child, etc.
* @return the newly created PSI element
*/
- @Nullable
+ @NotNull
public abstract T createFromText(LanguageLevel langLevel, Class aClass, final String text, final int[] path);
public abstract PyNamedParameter createParameter(@NotNull String name);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
index af06d7f8ba71..d379a505ecfa 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
@@ -197,9 +197,6 @@ public class PyBuiltinCache {
private final Map> myStdlibTypeCache = new HashMap>();
private long myModStamp = -1;
- /**
- @return
- */
@Nullable
public PyClassType getObjectType(@NonNls String name) {
PyClassType val;
@@ -216,11 +213,15 @@ public class PyBuiltinCache {
PyClass cls = getClass(name);
if (cls != null) { // null may happen during testing
val = new PyClassType(cls, false);
+ val.assertValid(name);
synchronized (myTypeCache) {
myTypeCache.put(name, val);
}
}
}
+ else {
+ val.assertValid(name);
+ }
return val;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
index 83a6bb7ff367..e67f44c05c4e 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
@@ -898,7 +898,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement
else if (anchor != null) {
PyResolveUtil.scopeCrawlUp(new PsiScopeProcessor() {
@Override
- public boolean execute(PsiElement element, ResolveState state) {
+ public boolean execute(@NotNull PsiElement element, ResolveState state) {
if (element instanceof PyAssignmentStatement) {
collectNewTargets(result, (PyAssignmentStatement)element);
}
@@ -907,7 +907,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement
@Nullable
@Override
- public T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java
index a30ffb871c94..c5030321122e 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java
@@ -19,6 +19,7 @@ import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
+import java.util.Arrays;
import java.util.Formatter;
/**
@@ -202,17 +203,17 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
throw new IncorrectOperationException("could not parse text as expression: " + text);
}
+ @NotNull
public PyCallExpression createCallExpression(final LanguageLevel langLevel, String functionName) {
final PsiFile dummyFile = createDummyFile(langLevel, functionName + "()");
final PsiElement child = dummyFile.getFirstChild();
if (child != null) {
final PsiElement element = child.getFirstChild();
- if (!(element instanceof PyCallExpression)) {
- throw new IllegalArgumentException("Invalid call expression text " + functionName);
+ if (element instanceof PyCallExpression) {
+ return (PyCallExpression)element;
}
- return (PyCallExpression)element;
}
- return null;
+ throw new IllegalArgumentException("Invalid call expression text " + functionName);
}
public PyImportStatement createImportStatementFromText(final String text) {
@@ -227,6 +228,7 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
static final int[] FROM_ROOT = new int[]{0};
+ @NotNull
public T createFromText(LanguageLevel langLevel, Class aClass, final String text) {
return createFromText(langLevel, aClass, text, FROM_ROOT);
}
@@ -237,7 +239,7 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
return createFromText(LanguageLevel.getDefault(), PyNamedParameter.class, "def f(" + name + "): pass", PATH_PARAMETER);
}
- // TODO: use to generate most other things
+ @NotNull
public T createFromText(LanguageLevel langLevel, Class aClass, final String text, final int[] path) {
PsiElement ret = createDummyFile(langLevel, text);
for (int skip : path) {
@@ -248,20 +250,24 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
ret = ret.getNextSibling();
}
else {
- return null;
+ ret = null;
+ break;
}
}
}
else {
- return null;
+ break;
}
}
+ if (ret == null) {
+ throw new IllegalArgumentException("Can't find element matching path " + Arrays.toString(path) + " in text '" + text + "'");
+ }
try {
//noinspection unchecked
return (T)ret;
}
catch (ClassCastException e) {
- return null;
+ throw new IllegalArgumentException("Can't create an expression of type " + aClass + " from text '" + text + "'");
}
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
index 35512c774fac..4f817901fcc5 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
@@ -3,17 +3,12 @@ package com.jetbrains.python.psi.impl;
import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.lang.Language;
import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
-import com.intellij.psi.util.CachedValue;
-import com.intellij.psi.util.CachedValueProvider;
-import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
@@ -33,20 +28,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.lang.ref.SoftReference;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
protected PyType myType;
private ThreadLocal> myFindExportedNameStack = new ArrayListThreadLocal();
- private final CachedValue> myImportTargetsTransitive;
//private volatile Boolean myAbsoluteImportEnabled;
private final Map myFutureFeatures;
private List myDunderAll;
private boolean myDunderAllCalculated;
- private final Map> myExportedNames = new ConcurrentHashMap>();
private volatile ExportedNameCache myExportedNameCache;
private final PsiModificationTracker myModificationTracker;
@@ -231,12 +222,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
public PyFileImpl(FileViewProvider viewProvider, Language language) {
super(viewProvider, language);
- myImportTargetsTransitive = CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider>() {
- @Override
- public Result> compute() {
- return new Result>(calculateImportTargetsTransitive(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
- }
- }, false);
myFutureFeatures = new HashMap();
myModificationTracker = PsiModificationTracker.SERVICE.getInstance(getProject());
}
@@ -326,7 +311,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
final List remainingDunderAll = dunderAll == null ? null : new ArrayList(dunderAll);
PsiScopeProcessor wrapper = new PsiScopeProcessor() {
@Override
- public boolean execute(PsiElement element, ResolveState state) {
+ public boolean execute(@NotNull PsiElement element, ResolveState state) {
if (!processor.execute(element, state)) return false;
if (remainingDunderAll != null && element instanceof PyElement) {
remainingDunderAll.remove(((PyElement) element).getName());
@@ -335,7 +320,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
}
@Override
- public T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return processor.getHint(hintKey);
}
@@ -411,36 +396,18 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
@Nullable
public PsiElement findExportedName(String name) {
- if (!Registry.is("python.exported.names.local.cache")) {
- final SoftReference ref = myExportedNames.get(name);
- if (ref != null) {
- final PsiElement result = ref.get();
- if (result != null) {
- return result;
- }
- }
- }
-
final List stack = myFindExportedNameStack.get();
if (stack.contains(name)) {
return null;
}
stack.add(name);
try {
- if (Registry.is("python.exported.names.local.cache")) {
- if (myExportedNameCache == null) {
- myExportedNameCache = new ExportedNameCache();
- }
- PsiElement result = myExportedNameCache.resolve(name);
- if (result != null) {
- return result;
- }
+ if (myExportedNameCache == null) {
+ myExportedNameCache = new ExportedNameCache();
}
- else {
- final PsiElement result = findExportedNameOldStyle(name);
- if (result != null) {
- return result;
- }
+ PsiElement result = myExportedNameCache.resolve(name);
+ if (result != null) {
+ return result;
}
List allNames = getDunderAll();
if (allNames != null && allNames.contains(name)) {
@@ -453,81 +420,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
}
}
- private PsiElement findExportedNameOldStyle(String name) {
- final List children = PyPsiUtils.collectAllStubChildren(this, getStub());
- final List exceptParts = new ArrayList();
- for (int i=children.size()-1; i >= 0; i--) {
- ProgressManager.checkCanceled();
- PsiElement child = children.get(i);
- if (child instanceof PyExceptPart) {
- exceptParts.add((PyExceptPart) child);
- }
- else {
- PsiElement element = findNameInStub(child, name);
- if (element != null) {
- myExportedNames.put(name, new SoftReference(element));
- return element;
- }
- }
- }
- for (int i = exceptParts.size() - 1; i >= 0; i--) {
- ProgressManager.checkCanceled();
- PyExceptPart part = exceptParts.get(i);
- final List exceptChildren = PyPsiUtils.collectAllStubChildren(part, part.getStub());
- for (int j = exceptChildren.size() - 1; j >= 0; j--) {
- PsiElement child = exceptChildren.get(j);
- PsiElement element = findNameInStub(child, name);
- if (element != null) {
- myExportedNames.put(name, new SoftReference(element));
- return element;
- }
- }
- }
- return null;
- }
-
- @Nullable
- private PsiElement findNameInStub(PsiElement child, String name) {
- if (child instanceof PsiNamedElement && name.equals(((PsiNamedElement)child).getName())) {
- return child;
- }
- else if (child instanceof PyFromImportStatement) {
- return findNameInFromImportStatement(name, (PyFromImportStatement)child);
- }
- else if (child instanceof PyImportStatement) {
- return findNameInImportStatement(name, (PyImportStatement)child);
- }
- return null;
- }
-
- @Nullable
- private PsiElement findNameInFromImportStatement(String name, PyFromImportStatement statement) {
- if (statement.isStarImport()) {
- return findNameInStarImport(name, statement);
- }
- else {
- for (PyImportElement importElement : statement.getImportElements()) {
- if (name.equals(importElement.getVisibleName())) {
- final PsiElement resolved = importElement.getElementNamed(name);
- if (resolved != null) {
- return resolved;
- }
- }
- }
- }
- // http://stackoverflow.com/questions/6048786/from-module-import-in-init-py-makes-module-name-visible
- if (PyNames.INIT_DOT_PY.equals(getName())) {
- final PyQualifiedName qName = statement.getImportSourceQName();
- if (qName != null && qName.endsWith(name)) {
- final PsiElement element = PyUtil.turnInitIntoDir(statement.resolveImportSource());
- if (element != null && element.getParent() == getContainingDirectory()) {
- return element;
- }
- }
- }
- return null;
- }
-
@Nullable
private PsiElement findNameInStarImport(String name, PyFromImportStatement statement) {
if (PyUtil.isClassPrivateName(name)) {
@@ -556,17 +448,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
return null;
}
- @Nullable
- private PsiElement findNameInImportStatement(String name, PyImportStatement child) {
- for (PyImportElement importElement: child.getImportElements()) {
- final PsiElement result = findNameInImportElement(name, importElement, false);
- if (result != null) {
- return result;
- }
- }
- return null;
- }
-
@Nullable
private PsiElement findNameInImportElement(String name, PyImportElement importElement, final boolean resolveImportElement) {
final PsiElement result = importElement.getElementNamed(name, resolveImportElement);
@@ -625,33 +506,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
return ret;
}
- public List getImportTargetsTransitive() {
- return myImportTargetsTransitive.getValue();
- }
-
- private List calculateImportTargetsTransitive() {
- Set visitedFiles = new HashSet();
- visitedFiles.add(this);
- List result = new ArrayList();
- calculateImportTargetsRecursive(this, visitedFiles, result);
- return result;
- }
-
- private static void calculateImportTargetsRecursive(PyFileImpl pyFile, Set visitedFiles, List result) {
- final List imports = pyFile.getImportTargets();
- for (PyImportElement anImport : imports) {
- result.add(anImport);
- final PsiElement resolveResult = ResolveImportUtil.resolveImportElement(anImport);
- if (resolveResult instanceof PyFileImpl) {
- PyFileImpl file = (PyFileImpl) resolveResult;
- if (!visitedFiles.contains(file)) {
- visitedFiles.add(file);
- calculateImportTargetsRecursive((PyFileImpl) resolveResult, visitedFiles, result);
- }
- }
- }
- }
-
public List getFromImports() {
return PyPsiUtils.collectStubChildren(this, getStub(), PyElementTypes.FROM_IMPORT_STATEMENT, PyFromImportStatement.class);
}
@@ -814,7 +668,6 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
ControlFlowCache.clear(this);
myDunderAllCalculated = false;
myFutureFeatures.clear(); // probably no need to synchronize
- myExportedNames.clear();
myExportedNameCache = null;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
index 4f44de8b9a9e..89cdbd62caac 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
@@ -195,11 +195,13 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp
for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
final PyType returnType = typeProvider.getReturnType(this, callSite, typeEvalContext);
if (returnType != null) {
+ returnType.assertValid(typeProvider.toString());
return returnType;
}
}
final PyType docStringType = getReturnTypeFromDocString();
if (docStringType != null) {
+ docStringType.assertValid("from docstring");
return docStringType;
}
if (typeEvalContext.allowReturnTypes(this)) {
diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
index 7297d3ce5627..2269f1e16ceb 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
@@ -474,15 +474,12 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl attrs = collectAssignedAttributes((PyQualifiedExpression)qualifier);
- variants.addAll(attrs);
for (PyExpression ex : attrs) {
+ if (ex instanceof PsiNamedElement && qualifierType instanceof PyClassType) {
+ variants.add(LookupElementBuilder.create((PsiNamedElement)ex)
+ .withTypeText(qualifierType.getName())
+ .withIcon(PlatformIcons.FIELD_ICON));
+ }
if (ex instanceof PyReferenceExpression) {
PyReferenceExpression refExpr = (PyReferenceExpression)ex;
namesAlready.add(refExpr.getReferencedName());
diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
index da07d32a06c2..05922e81ed67 100644
--- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
@@ -518,7 +518,6 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
PythonDataflowUtil.collectFunctionArgNames(element, ret);
// include builtin names
- processor.setNotice("__builtin__");
final PyFile builtinsFile = PyBuiltinCache.getInstance(element).getBuiltinsFile();
if (builtinsFile != null) {
PyResolveUtil.scopeCrawlUp(processor, builtinsFile, null);
diff --git a/python/src/com/jetbrains/python/psi/resolve/AssignmentCollectProcessor.java b/python/src/com/jetbrains/python/psi/resolve/AssignmentCollectProcessor.java
index b7f374c84a6b..ff01a27fb339 100644
--- a/python/src/com/jetbrains/python/psi/resolve/AssignmentCollectProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/AssignmentCollectProcessor.java
@@ -34,7 +34,7 @@ public class AssignmentCollectProcessor implements PsiScopeProcessor {
mySeenNames = new HashSet();
}
- public boolean execute(final PsiElement element, final ResolveState state) {
+ public boolean execute(@NotNull final PsiElement element, final ResolveState state) {
if (element instanceof PyAssignmentStatement) {
final PyAssignmentStatement assignment = (PyAssignmentStatement)element;
for (PyExpression ex : assignment.getTargets()) {
@@ -69,7 +69,7 @@ public class AssignmentCollectProcessor implements PsiScopeProcessor {
return myResult;
}
- public T getHint(final Key hintKey) {
+ public T getHint(@NotNull final Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/CollectProcessor.java b/python/src/com/jetbrains/python/psi/resolve/CollectProcessor.java
index 368dbff72957..8ff69dfcad6d 100644
--- a/python/src/com/jetbrains/python/psi/resolve/CollectProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/CollectProcessor.java
@@ -18,14 +18,14 @@ public class CollectProcessor implements PyClassScopeProcessor {
myResult = new ArrayList();
}
- public boolean execute(final PsiElement element, final ResolveState state) {
+ public boolean execute(@NotNull final PsiElement element, final ResolveState state) {
if (myTargetTokenSet.contains(element.getNode().getElementType())) {
myResult.add(element);
}
return true; // collect till we drop
}
- public T getHint(final Key hintKey) {
+ public T getHint(@NotNull final Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
index 8836064543dc..8011eef745d2 100644
--- a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java
@@ -11,10 +11,11 @@ import com.intellij.util.PlatformIcons;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.completion.PyClassInsertHandler;
import com.jetbrains.python.codeInsight.completion.PyFunctionInsertHandler;
+import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
+import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
-import com.jetbrains.python.psi.types.PyType;
-import com.jetbrains.python.psi.types.TypeEvalContext;
+import com.jetbrains.python.psi.impl.PyQualifiedName;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,12 +43,13 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
}
protected LookupElementBuilder setupItem(LookupElementBuilder item) {
+ final Object object = item.getObject();
if (!myPlainNamesOnly) {
if (!mySuppressParentheses &&
- item.getObject() instanceof PyFunction && ((PyFunction) item.getObject()).getProperty() == null &&
- !isSingleArgDecoratorCall(myContext, (PyFunction)item.getObject())) {
+ object instanceof PyFunction && ((PyFunction)object).getProperty() == null &&
+ !isSingleArgDecoratorCall(myContext, (PyFunction)object)) {
item = item.withInsertHandler(PyFunctionInsertHandler.INSTANCE);
- final PyParameterList parameterList = ((PyFunction)item.getObject()).getParameterList();
+ final PyParameterList parameterList = ((PyFunction)object).getParameterList();
final String params = StringUtil.join(parameterList.getParameters(), new Function() {
@Override
public String fun(PyParameter pyParameter) {
@@ -56,12 +58,46 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
}, ", ");
item = item.withTailText("(" + params + ")");
}
- else if (item.getObject() instanceof PyClass) {
+ else if (object instanceof PyClass) {
item = item.withInsertHandler(PyClassInsertHandler.INSTANCE);
}
}
- if (myNotice != null) {
- return setItemNotice(item, myNotice);
+ String source = null;
+ if (object instanceof PsiElement) {
+ final PsiElement element = (PsiElement)object;
+ PyClass cls = null;
+
+ if (element instanceof PyFunction) {
+ cls = ((PyFunction)element).getContainingClass();
+ }
+ else if (element instanceof PyTargetExpression) {
+ final PyTargetExpression expr = (PyTargetExpression)element;
+ if (expr.getQualifier() != null || ScopeUtil.getScopeOwner(expr) instanceof PyClass) {
+ cls = expr.getContainingClass();
+ }
+ }
+ else if (element instanceof PyClass) {
+ final ScopeOwner owner = ScopeUtil.getScopeOwner(element);
+ if (owner instanceof PyClass) {
+ cls = (PyClass)owner;
+ }
+ }
+
+ if (cls != null) {
+ source = cls.getName();
+ }
+ else if (myContext == null || !PyUtil.inSameFile(myContext, element)) {
+ PyQualifiedName path = ResolveImportUtil.findCanonicalImportPath(element, null);
+ if (path != null) {
+ if (element instanceof PyFile) {
+ path = path.removeLastComponent();
+ }
+ source = path.toString();
+ }
+ }
+ }
+ if (source != null) {
+ item = item.withTypeText(source);
}
return item;
}
@@ -107,22 +143,6 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
// things like PyTargetExpression cannot have a general icon, but here we only have variables
if (icon == null) icon = PlatformIcons.VARIABLE_ICON;
LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(expr, referencedName).withIcon(icon));
- if (definer instanceof PyImportElement) { // set notice to imported module name if needed
- PsiElement maybeFromImport = definer.getParent();
- if (maybeFromImport instanceof PyFromImportStatement) {
- final PyFromImportStatement fromImport = (PyFromImportStatement)maybeFromImport;
- PyReferenceExpression src = fromImport.getImportSource();
- if (src != null) {
- lookupItem = setItemNotice(lookupItem, src.getName());
- }
- }
- }
- if (definer instanceof PyAssignmentStatement && expr instanceof PyExpression) {
- PyType type = ((PyExpression) expr).getType(TypeEvalContext.fast());
- if (type != null) {
- lookupItem = lookupItem.withTypeText(type.getName());
- }
- }
myVariants.put(referencedName, lookupItem);
}
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveProcessor.java b/python/src/com/jetbrains/python/psi/resolve/ResolveProcessor.java
index c2ec399ef351..ff96a2e379a9 100644
--- a/python/src/com/jetbrains/python/psi/resolve/ResolveProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/ResolveProcessor.java
@@ -48,7 +48,7 @@ public class ResolveProcessor implements PsiScopeProcessor {
return PyUtil.nvl(myName) + ", " + PyUtil.nvl(myResult);
}
- public boolean execute(PsiElement element, ResolveState substitutor) {
+ public boolean execute(@NotNull PsiElement element, ResolveState substitutor) {
if (element instanceof PyFile) {
final VirtualFile file = ((PyFile)element).getVirtualFile();
if (file != null) {
@@ -139,7 +139,7 @@ public class ResolveProcessor implements PsiScopeProcessor {
}
@Nullable
- public T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java
index 4246bd0aaa4f..2cc058e6c529 100644
--- a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java
+++ b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java
@@ -4,11 +4,13 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiInvalidElementAccessException;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyQualifiedName;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -16,7 +18,6 @@ import java.util.List;
public abstract class VariantsProcessor implements PsiScopeProcessor {
protected final PsiElement myContext;
- protected String myNotice;
protected Condition myNodeFilter;
protected Condition myNameFilter;
@@ -35,10 +36,6 @@ public abstract class VariantsProcessor implements PsiScopeProcessor {
myNameFilter = nameFilter;
}
- public void setNotice(@Nullable String notice) {
- myNotice = notice;
- }
-
public boolean isPlainNamesOnly() {
return myPlainNamesOnly;
}
@@ -48,7 +45,7 @@ public abstract class VariantsProcessor implements PsiScopeProcessor {
}
- public boolean execute(PsiElement element, ResolveState substitutor) {
+ public boolean execute(@NotNull PsiElement element, ResolveState substitutor) {
if (myNodeFilter != null && !myNodeFilter.value(element)) return true; // skip whatever the filter rejects
// TODO: refactor to look saner; much code duplication
if (element instanceof PsiNamedElement) {
@@ -77,7 +74,10 @@ public abstract class VariantsProcessor implements PsiScopeProcessor {
final NameDefiner definer = (NameDefiner)element;
for (PyElement expr : definer.iterateNames()) {
if (expr != null && expr != myContext) { // NOTE: maybe rather have SingleIterables skip nulls outright?
- String referencedName = expr instanceof PyFile ? FileUtil.getNameWithoutExtension(((PyFile) expr).getName()) : expr.getName();
+ if (!expr.isValid()) {
+ throw new PsiInvalidElementAccessException(expr, "Definer: " + definer);
+ }
+ String referencedName = expr instanceof PyFile ? FileUtil.getNameWithoutExtension(((PyFile)expr).getName()) : expr.getName();
if (referencedName != null && nameIsAcceptable(referencedName)) {
addImportedElement(referencedName, definer, expr);
}
@@ -129,7 +129,7 @@ public abstract class VariantsProcessor implements PsiScopeProcessor {
}
@Nullable
- public T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyClassType.java b/python/src/com/jetbrains/python/psi/types/PyClassType.java
index 68d80309a2b0..be4f90269bc4 100644
--- a/python/src/com/jetbrains/python/psi/types/PyClassType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyClassType.java
@@ -270,7 +270,7 @@ public class PyClassType extends UserDataHolderBase implements PyCallableType {
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
for (PyDynamicMember member : provider.getMembers(this)) {
final String name = member.getName();
- ret.add(LookupElementBuilder.create(name).withIcon(member.getIcon()).withTypeText(member.getShortType()));
+ ret.add(LookupElementBuilder.create(name).withIcon(member.getIcon()).withTypeText(getName()));
}
}
@@ -310,7 +310,6 @@ public class PyClassType extends UserDataHolderBase implements PyCallableType {
final CompletionVariantsProcessor processor = new CompletionVariantsProcessor(
expressionHook, new PyResolveUtil.FilterNotInstance(myClass), null
);
- processor.setNotice(myClass.getName());
if (suppressParentheses) {
processor.suppressParentheses();
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java
index 74e75957e946..53b65d57de0a 100644
--- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java
@@ -167,7 +167,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
final List visibleImports = new ArrayList();
PyResolveUtil.scopeCrawlUp(new PsiScopeProcessor() {
@Override
- public boolean execute(PsiElement element, ResolveState state) {
+ public boolean execute(@NotNull PsiElement element, ResolveState state) {
if (element instanceof PyImportElement) {
visibleImports.add((PyImportElement)element);
}
@@ -176,7 +176,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
@Nullable
@Override
- public T getHint(Key hintKey) {
+ public T getHint(@NotNull Key hintKey) {
return null;
}
diff --git a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
index 684aab755a48..8064388b07eb 100644
--- a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
+++ b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java
@@ -27,23 +27,22 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams,
private JCheckBox myAttachDebuggerToSubprocess;
private final AbstractPyCommonOptionsForm myCommonOptionsForm;
private JComponent anchor;
- private final Project myProject;
public PythonRunConfigurationForm(PythonRunConfiguration configuration) {
myCommonOptionsForm = PyCommonOptionsFormFactory.getInstance().createForm(configuration.getCommonOptionsFormData());
myCommonOptionsPlaceholder.add(myCommonOptionsForm.getMainPanel(), BorderLayout.CENTER);
- myProject = configuration.getProject();
+ Project project = configuration.getProject();
FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- return file.isDirectory() || Comparing.equal(file.getExtension(), "py");
+ return file.isDirectory() || file.getExtension() == null || Comparing.equal(file.getExtension(), "py");
}
};
//chooserDescriptor.setRoot(s.getProject().getBaseDir());
ComponentWithBrowseButton.BrowseFolderActionListener listener =
- new ComponentWithBrowseButton.BrowseFolderActionListener("Select Script", "", myScriptTextField, myProject,
+ new ComponentWithBrowseButton.BrowseFolderActionListener("Select Script", "", myScriptTextField, project,
chooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
protected void onFileChoosen(VirtualFile chosenFile) {
diff --git a/python/testData/completion/elif.after.py b/python/testData/completion/elif.after.py
index 2be265063334..432aaceb5a03 100644
--- a/python/testData/completion/elif.after.py
+++ b/python/testData/completion/elif.after.py
@@ -1,3 +1,3 @@
if True:
a = 1
-elif :
\ No newline at end of file
+elif
\ No newline at end of file
diff --git a/python/testData/completion/elifNotIndented.after.py b/python/testData/completion/elifNotIndented.after.py
index 2be265063334..432aaceb5a03 100644
--- a/python/testData/completion/elifNotIndented.after.py
+++ b/python/testData/completion/elifNotIndented.after.py
@@ -1,3 +1,3 @@
if True:
a = 1
-elif :
\ No newline at end of file
+elif
\ No newline at end of file
diff --git a/python/testData/completion/except.after.py b/python/testData/completion/except.after.py
index a397d92696ac..c40febf7b710 100644
--- a/python/testData/completion/except.after.py
+++ b/python/testData/completion/except.after.py
@@ -1,3 +1,3 @@
try:
a = 1
-except :
\ No newline at end of file
+except
\ No newline at end of file
diff --git a/python/testData/completion/exceptNotIndented.after.py b/python/testData/completion/exceptNotIndented.after.py
index a397d92696ac..c40febf7b710 100644
--- a/python/testData/completion/exceptNotIndented.after.py
+++ b/python/testData/completion/exceptNotIndented.after.py
@@ -1,3 +1,3 @@
try:
a = 1
-except :
\ No newline at end of file
+except
\ No newline at end of file