diff options
Diffstat (limited to 'python/src/com/jetbrains/python/psi')
11 files changed, 195 insertions, 146 deletions
diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index cd4e582bb6f2..dc5cbf4917a5 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1394,8 +1394,8 @@ public class PyUtil { @Nullable public static PsiElement findPrevAtOffset(PsiFile psiFile, int caretOffset, Class... toSkip) { - PsiElement element = psiFile.findElementAt(caretOffset); - if (element == null || caretOffset < 0) { + PsiElement element; + if (caretOffset < 0) { return null; } int lineStartOffset = 0; diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index bb2104fc0c77..611cbc84ad2e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -17,6 +17,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyValue; @@ -53,10 +54,13 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; +import static com.intellij.openapi.util.text.StringUtil.join; +import static com.intellij.openapi.util.text.StringUtil.notNullize; + /** * @author yole */ -public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implements PyClass { +public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyClass { public static final PyClass[] EMPTY_ARRAY = new PyClassImpl[0]; private List<PyTargetExpression> myInstanceAttributes; @@ -288,6 +292,32 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement return result.toArray(new PyClass[result.size()]); } + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this) { + @Nullable + @Override + public String getPresentableText() { + if (!isValid()) { + return null; + } + final StringBuilder result = new StringBuilder(notNullize(getName(), PyNames.UNNAMED_ELEMENT)); + final PyExpression[] superClassExpressions = getSuperClassExpressions(); + if (superClassExpressions.length > 0) { + result.append("("); + result.append(join(Arrays.asList(superClassExpressions), new Function<PyExpression, String>() { + public String fun(PyExpression expr) { + String name = expr.getText(); + return notNullize(name, PyNames.UNNAMED_ELEMENT); + } + }, ", ")); + result.append(")"); + } + return result.toString(); + } + }; + } + @NotNull private static List<PyClassLikeType> mroMerge(@NotNull List<List<PyClassLikeType>> sequences) { List<PyClassLikeType> result = new LinkedList<PyClassLikeType>(); // need to insert to 0th position on linearize diff --git a/python/src/com/jetbrains/python/psi/impl/PyElementPresentation.java b/python/src/com/jetbrains/python/psi/impl/PyElementPresentation.java new file mode 100644 index 000000000000..7888071c7321 --- /dev/null +++ b/python/src/com/jetbrains/python/psi/impl/PyElementPresentation.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.psi.impl; + +import com.intellij.navigation.ColoredItemPresentation; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.jetbrains.python.PyNames; +import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.psi.resolve.QualifiedNameFinder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** +* @author vlan +*/ +public class PyElementPresentation implements ColoredItemPresentation { + @NotNull private final PyElement myElement; + + public PyElementPresentation(@NotNull PyElement element) { + myElement = element; + } + + @Nullable + @Override + public TextAttributesKey getTextAttributesKey() { + return null; + } + + @Nullable + @Override + public String getPresentableText() { + final String name = myElement.getName(); + return name != null ? name : PyNames.UNNAMED_ELEMENT; + } + + @Nullable + @Override + public String getLocationString() { + return "(" + getPackageForFile(myElement.getContainingFile()) + ")"; + } + + @Nullable + @Override + public Icon getIcon(boolean unused) { + return myElement.getIcon(0); + } + + public static String getPackageForFile(@NotNull PsiFile containingFile) { + final VirtualFile vFile = containingFile.getVirtualFile(); + + if (vFile != null) { + final String importableName = QualifiedNameFinder.findShortestImportableName(containingFile, vFile); + if (importableName != null) { + return importableName; + } + } + return ""; + } +} diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 86f84abb7fb6..2c1842f3337f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -16,6 +16,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; @@ -54,6 +55,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; +import static com.intellij.openapi.util.text.StringUtil.notNullize; import static com.jetbrains.python.psi.PyFunction.Modifier.CLASSMETHOD; import static com.jetbrains.python.psi.PyFunction.Modifier.STATICMETHOD; import static com.jetbrains.python.psi.impl.PyCallExpressionHelper.interpretAsModifierWrappingCall; @@ -61,7 +63,7 @@ import static com.jetbrains.python.psi.impl.PyCallExpressionHelper.interpretAsMo /** * Implements PyFunction. */ -public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> implements PyFunction { +public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements PyFunction { public PyFunctionImpl(ASTNode astNode) { super(astNode); @@ -259,6 +261,17 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp return type; } + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this) { + @Nullable + @Override + public String getPresentableText() { + return notNullize(getName(), PyNames.UNNAMED_ELEMENT) + getParameterList().getPresentableText(true); + } + }; + } + @Nullable private PyType replaceSelf(@Nullable PyType returnType, @Nullable PyExpression receiver, @NotNull TypeEvalContext context) { if (receiver != null) { @@ -292,32 +305,30 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp final PyBuiltinCache cache = PyBuiltinCache.getInstance(this); final PyStatementList statements = getStatementList(); final Set<PyType> types = new LinkedHashSet<PyType>(); - if (statements != null) { - statements.accept(new PyRecursiveElementVisitor() { - @Override - public void visitPyYieldExpression(PyYieldExpression node) { - final PyType type = context.getType(node); - if (node.isDelegating() && type instanceof PyCollectionType) { - final PyCollectionType collectionType = (PyCollectionType)type; - types.add(collectionType.getElementType(context)); - } - else { - types.add(type); - } + statements.accept(new PyRecursiveElementVisitor() { + @Override + public void visitPyYieldExpression(PyYieldExpression node) { + final PyType type = context.getType(node); + if (node.isDelegating() && type instanceof PyCollectionType) { + final PyCollectionType collectionType = (PyCollectionType)type; + types.add(collectionType.getElementType(context)); } - - @Override - public void visitPyFunction(PyFunction node) { - // Ignore nested functions + else { + types.add(type); } - }); - final int n = types.size(); - if (n == 1) { - elementType = Ref.create(types.iterator().next()); } - else if (n > 0) { - elementType = Ref.create(PyUnionType.union(types)); + + @Override + public void visitPyFunction(PyFunction node) { + // Ignore nested functions } + }); + final int n = types.size(); + if (n == 1) { + elementType = Ref.create(types.iterator().next()); + } + else if (n > 0) { + elementType = Ref.create(PyUnionType.union(types)); } if (elementType != null) { final PyClass generator = cache.getClass(PyNames.FAKE_GENERATOR); @@ -335,14 +346,12 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp public PyType getReturnStatementType(TypeEvalContext typeEvalContext) { ReturnVisitor visitor = new ReturnVisitor(this, typeEvalContext); final PyStatementList statements = getStatementList(); - if (statements != null) { - statements.accept(visitor); - if (isGeneratedStub() && !visitor.myHasReturns) { - if (PyNames.INIT.equals(getName())) { - return PyNoneType.INSTANCE; - } - return null; + statements.accept(visitor); + if (isGeneratedStub() && !visitor.myHasReturns) { + if (PyNames.INIT.equals(getName())) { + return PyNoneType.INSTANCE; } + return null; } return visitor.result(); } @@ -376,9 +385,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp @Nullable public String extractDeprecationMessage() { PyStatementList statementList = getStatementList(); - if (statementList == null) { - return null; - } return extractDeprecationMessage(Arrays.asList(statementList.getStatements())); } @@ -430,7 +436,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp @Nullable @Override public StructuredDocString getStructuredDocString() { - return CachedValuesManager.getManager(getProject()).getCachedValue(this, myCachedStructuredDocStringProvider); + return CachedValuesManager.getCachedValue(this, myCachedStructuredDocStringProvider); } private boolean isGeneratedStub() { @@ -527,15 +533,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp public PyStringLiteralExpression getDocStringExpression() { final PyStatementList stmtList = getStatementList(); - return stmtList != null ? DocStringUtil.findDocStringExpression(stmtList) : null; - } - - protected String getElementLocation() { - final PyClass containingClass = getContainingClass(); - if (containingClass != null) { - return "(" + containingClass.getName() + " in " + getPackageForFile(getContainingFile()) + ")"; - } - return super.getElementLocation(); + return DocStringUtil.findDocStringExpression(stmtList); } @NotNull diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java index cc9178c07f9e..64108441c347 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java @@ -16,6 +16,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -48,7 +49,7 @@ import java.util.Map; /** * @author yole */ -public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParameterStub> implements PyNamedParameter { +public class PyNamedParameterImpl extends PyBaseElementImpl<PyNamedParameterStub> implements PyNamedParameter { public PyNamedParameterImpl(ASTNode astNode) { super(astNode); } @@ -280,6 +281,11 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame return null; } + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this); + } + private static void processLocalCalls(@NotNull PyFunction function, @NotNull Processor<PyCallExpression> processor) { final PsiFile file = function.getContainingFile(); final String name = function.getName(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyPresentableElementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyPresentableElementImpl.java deleted file mode 100644 index d04d04062651..000000000000 --- a/python/src/com/jetbrains/python/psi/impl/PyPresentableElementImpl.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jetbrains.python.psi.impl; - -import com.intellij.lang.ASTNode; -import com.intellij.navigation.ItemPresentation; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiNamedElement; -import com.intellij.psi.stubs.IStubElementType; -import com.intellij.psi.stubs.StubElement; -import com.jetbrains.python.psi.resolve.QualifiedNameFinder; - -import javax.swing.*; - -/** - * @author yole - */ -public abstract class PyPresentableElementImpl<T extends StubElement> extends PyBaseElementImpl<T> implements PsiNamedElement { - public PyPresentableElementImpl(ASTNode astNode) { - super(astNode); - } - - protected PyPresentableElementImpl(final T stub, final IStubElementType nodeType) { - super(stub, nodeType); - } - - public ItemPresentation getPresentation() { - return new ItemPresentation() { - public String getPresentableText() { - final String name = getName(); - return name != null ? name : "<none>"; - } - - public String getLocationString() { - return getElementLocation(); - } - - public Icon getIcon(final boolean open) { - return PyPresentableElementImpl.this.getIcon(0); - } - }; - } - - protected String getElementLocation() { - return "(" + getPackageForFile(getContainingFile()) + ")"; - } - - public static String getPackageForFile(final PsiFile containingFile) { - final VirtualFile vFile = containingFile.getVirtualFile(); - - if (vFile != null) { - final String importableName = QualifiedNameFinder.findShortestImportableName(containingFile, vFile); - if (importableName != null) { - return importableName; - } - } - return ""; - } -} diff --git a/python/src/com/jetbrains/python/psi/impl/PySingleStarParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PySingleStarParameterImpl.java index 70a46fbe39f9..44a01759f403 100644 --- a/python/src/com/jetbrains/python/psi/impl/PySingleStarParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PySingleStarParameterImpl.java @@ -16,21 +16,18 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.util.IncorrectOperationException; +import com.intellij.navigation.ItemPresentation; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyNamedParameter; import com.jetbrains.python.psi.PySingleStarParameter; import com.jetbrains.python.psi.PyTupleParameter; import com.jetbrains.python.psi.stubs.PySingleStarParameterStub; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; /** * @author yole */ -public class PySingleStarParameterImpl extends PyPresentableElementImpl<PySingleStarParameterStub> implements PySingleStarParameter { +public class PySingleStarParameterImpl extends PyBaseElementImpl<PySingleStarParameterStub> implements PySingleStarParameter { public PySingleStarParameterImpl(ASTNode astNode) { super(astNode); } @@ -39,22 +36,22 @@ public class PySingleStarParameterImpl extends PyPresentableElementImpl<PySingle super(stub, PyElementTypes.SINGLE_STAR_PARAMETER); } - public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { - throw new UnsupportedOperationException(); - } - + @Override public PyNamedParameter getAsNamed() { return null; } + @Override public PyTupleParameter getAsTuple() { return null; } + @Override public PyExpression getDefaultValue() { return null; } + @Override public boolean hasDefaultValue() { return false; } @@ -63,4 +60,9 @@ public class PySingleStarParameterImpl extends PyPresentableElementImpl<PySingle public boolean isSelf() { return false; } + + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this); + } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java index bf519737f0f4..084aeecc3df0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java @@ -327,7 +327,7 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt @Nullable @Override public String getLocationString() { - return "(" + PyPresentableElementImpl.getPackageForFile(getContainingFile()) + ")"; + return "(" + PyElementPresentation.getPackageForFile(getContainingFile()) + ")"; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index 3805c8df525e..d125190b77e9 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -16,6 +16,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; @@ -61,7 +62,7 @@ import java.util.List; /** * @author yole */ -public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExpressionStub> implements PyTargetExpression { +public class PyTargetExpressionImpl extends PyBaseElementImpl<PyTargetExpressionStub> implements PyTargetExpression { QualifiedName myQualifiedName; public PyTargetExpressionImpl(ASTNode astNode) { @@ -659,12 +660,19 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp return null; } - protected String getElementLocation() { - final PyClass containingClass = getContainingClass(); - if (containingClass != null) { - return "(" + containingClass.getName() + " in " + getPackageForFile(getContainingFile()) + ")"; - } - return super.getElementLocation(); + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this) { + @Nullable + @Override + public String getLocationString() { + final PyClass containingClass = getContainingClass(); + if (containingClass != null) { + return "(" + containingClass.getName() + " in " + getPackageForFile(getContainingFile()) + ")"; + } + return super.getLocationString(); + } + }; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/impl/PyTupleParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTupleParameterImpl.java index 09e097cb0e99..9935841c33bb 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTupleParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTupleParameterImpl.java @@ -16,19 +16,17 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.util.IncorrectOperationException; +import com.intellij.navigation.ItemPresentation; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PythonDialectsTokenSetProvider; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.stubs.PyTupleParameterStub; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; /** * Represents a tuple parameter as stubbed element. */ -public class PyTupleParameterImpl extends PyPresentableElementImpl<PyTupleParameterStub> implements PyTupleParameter { +public class PyTupleParameterImpl extends PyBaseElementImpl<PyTupleParameterStub> implements PyTupleParameter { public PyTupleParameterImpl(ASTNode astNode) { super(astNode); @@ -62,10 +60,6 @@ public class PyTupleParameterImpl extends PyPresentableElementImpl<PyTupleParame return getDefaultValue() != null; } - public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { - throw new IncorrectOperationException("Can't rename a tuple parameter to '" + name +"'"); - } - @Override protected void acceptPyVisitor(PyElementVisitor pyVisitor) { pyVisitor.visitPyTupleParameter(this); @@ -80,4 +74,9 @@ public class PyTupleParameterImpl extends PyPresentableElementImpl<PyTupleParame public boolean isSelf() { return false; } + + @Override + public ItemPresentation getPresentation() { + return new PyElementPresentation(this); + } } diff --git a/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java b/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java index 7e15cab6ffda..af767684643e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java +++ b/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java @@ -19,7 +19,9 @@ import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleType; @@ -163,7 +165,8 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<LanguageLev oStream.close(); for (VirtualFile child : fileOrDir.getChildren()) { - if (!child.isDirectory() && PythonFileType.INSTANCE.equals(child.getFileType())) { + final FileType fileType = FileTypeRegistry.getInstance().getFileTypeByFileName(child.getName()); + if (!child.isDirectory() && PythonFileType.INSTANCE.equals(fileType)) { PushedFilePropertiesUpdater.getInstance(project).filePropertiesChanged(child); } } |