Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2012-06-14 13:39:12 +04:00
28 changed files with 151 additions and 272 deletions
-5
View File
@@ -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 = '<var name="%s" type="%s"' % (makeValidXmlValue(quote(name, '/>_= ')), 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:
@@ -1,5 +1,5 @@
<component>
<version codename="2.1 EAP" major="2" minor="1" eap="true" update-channel="pycharm2EAP"/>
<version codename="2.6 EAP" major="2" minor="6" eap="true" update-channel="pycharm2EAP"/>
<build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
<logo url="/pycharm_logo.png" textcolor="B7C9B5"/>
<about url="/pycharm_about.png"/>
@@ -50,7 +50,7 @@ public class PyDunderAllReference extends PsiReferenceBase<PyStringLiteralExpres
final List<String> 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<PyStringLiteralExpres
}
@Override
public <T> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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();
@@ -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
@@ -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> T createFromText(LanguageLevel langLevel, Class<T> 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> T createFromText(LanguageLevel langLevel, Class<T> aClass, final String text, final int[] path);
public abstract PyNamedParameter createParameter(@NotNull String name);
@@ -197,9 +197,6 @@ public class PyBuiltinCache {
private final Map<String, Ref<PyType>> myStdlibTypeCache = new HashMap<String, Ref<PyType>>();
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;
}
@@ -898,7 +898,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> 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<PyClassStub> implement
@Nullable
@Override
public <T> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@@ -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> T createFromText(LanguageLevel langLevel, Class<T> 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> T createFromText(LanguageLevel langLevel, Class<T> 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 + "'");
}
}
@@ -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<List<String>> myFindExportedNameStack = new ArrayListThreadLocal();
private final CachedValue<List<PyImportElement>> myImportTargetsTransitive;
//private volatile Boolean myAbsoluteImportEnabled;
private final Map<FutureFeature, Boolean> myFutureFeatures;
private List<String> myDunderAll;
private boolean myDunderAllCalculated;
private final Map<String, SoftReference<PsiElement>> myExportedNames = new ConcurrentHashMap<String, SoftReference<PsiElement>>();
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<List<PyImportElement>>() {
@Override
public Result<List<PyImportElement>> compute() {
return new Result<List<PyImportElement>>(calculateImportTargetsTransitive(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
}
}, false);
myFutureFeatures = new HashMap<FutureFeature, Boolean>();
myModificationTracker = PsiModificationTracker.SERVICE.getInstance(getProject());
}
@@ -326,7 +311,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
final List<String> remainingDunderAll = dunderAll == null ? null : new ArrayList<String>(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> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> 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<PsiElement> ref = myExportedNames.get(name);
if (ref != null) {
final PsiElement result = ref.get();
if (result != null) {
return result;
}
}
}
final List<String> 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<String> 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<PsiElement> children = PyPsiUtils.collectAllStubChildren(this, getStub());
final List<PyExceptPart> exceptParts = new ArrayList<PyExceptPart>();
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<PsiElement>(element));
return element;
}
}
}
for (int i = exceptParts.size() - 1; i >= 0; i--) {
ProgressManager.checkCanceled();
PyExceptPart part = exceptParts.get(i);
final List<PsiElement> 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<PsiElement>(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<PyImportElement> getImportTargetsTransitive() {
return myImportTargetsTransitive.getValue();
}
private List<PyImportElement> calculateImportTargetsTransitive() {
Set<PyFile> visitedFiles = new HashSet<PyFile>();
visitedFiles.add(this);
List<PyImportElement> result = new ArrayList<PyImportElement>();
calculateImportTargetsRecursive(this, visitedFiles, result);
return result;
}
private static void calculateImportTargetsRecursive(PyFileImpl pyFile, Set<PyFile> visitedFiles, List<PyImportElement> result) {
final List<PyImportElement> 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<PyFromImportStatement> 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;
}
@@ -195,11 +195,13 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> 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)) {
@@ -474,15 +474,12 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
return null;
}
PsiElement parent = PsiTreeUtil.getParentOfType(this, PyStatementList.class);
if (parent != null) {
PsiElement pparent = parent.getParent();
if (pparent instanceof PyClass) {
return (PyClass)pparent;
}
if (pparent instanceof PyFunction) {
return ((PyFunction) pparent).getContainingClass();
}
final PsiElement parent = PsiTreeUtil.getParentOfType(this, PyFunction.class, PyClass.class);
if (parent instanceof PyClass) {
return (PyClass)parent;
}
if (parent instanceof PyFunction) {
return ((PyFunction)parent).getContainingClass();
}
return null;
}
@@ -11,11 +11,13 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.stubs.StubUpdatingIndex;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.ProcessingContext;
import com.intellij.util.indexing.FileBasedIndex;
import com.jetbrains.cython.types.CythonStructType;
@@ -250,8 +252,12 @@ public class PyQualifiedReference extends PyReferenceImpl {
Collections.addAll(variants, getVariantFromHasAttr(qualifier));
if (qualifier instanceof PyQualifiedExpression) {
Collection<PyExpression> 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());
@@ -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);
@@ -34,7 +34,7 @@ public class AssignmentCollectProcessor implements PsiScopeProcessor {
mySeenNames = new HashSet<String>();
}
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> T getHint(final Key<T> hintKey) {
public <T> T getHint(@NotNull final Key<T> hintKey) {
return null;
}
@@ -18,14 +18,14 @@ public class CollectProcessor implements PyClassScopeProcessor {
myResult = new ArrayList<PsiElement>();
}
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> T getHint(final Key<T> hintKey) {
public <T> T getHint(@NotNull final Key<T> hintKey) {
return null;
}
@@ -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<PyParameter, String>() {
@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);
}
}
@@ -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> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@@ -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<PsiElement> myNodeFilter;
protected Condition<String> 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> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@@ -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();
}
@@ -167,7 +167,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
final List<PyImportElement> visibleImports = new ArrayList<PyImportElement>();
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> T getHint(Key<T> hintKey) {
public <T> T getHint(@NotNull Key<T> hintKey) {
return null;
}
@@ -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<JTextField> listener =
new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>("Select Script", "", myScriptTextField, myProject,
new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>("Select Script", "", myScriptTextField, project,
chooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
protected void onFileChoosen(VirtualFile chosenFile) {
+1 -1
View File
@@ -1,3 +1,3 @@
if True:
a = 1
elif <caret>:
elif<caret>
@@ -1,3 +1,3 @@
if True:
a = 1
elif <caret>:
elif<caret>
+1 -1
View File
@@ -1,3 +1,3 @@
try:
a = 1
except <caret>:
except<caret>
@@ -1,3 +1,3 @@
try:
a = 1
except <caret>:
except<caret>