Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2012-08-30 17:37:59 +04:00
50 changed files with 396 additions and 163 deletions
@@ -0,0 +1,14 @@
package icons;
import com.intellij.openapi.util.IconLoader;
import javax.swing.*;
/**
* NOTE THIS FILE IS AUTO-GENERATED by the build/scripts/icons.gant
* Don't repeat mistakes of others ;-)
*/
public class PythonHelpersIcons {
public static final Icon Keybd_closed = IconLoader.getIcon("/coverage/htmlfiles/keybd_closed.png"); // 35x12
public static final Icon Keybd_open = IconLoader.getIcon("/coverage/htmlfiles/keybd_open.png"); // 35x12
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.psi;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public class WeakFileReference extends FileReference implements PsiReferenceEx {
public WeakFileReference(FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
super(fileReferenceSet, range, index, text);
}
@Nullable
@Override
public HighlightSeverity getUnresolvedHighlightSeverity(TypeEvalContext context) {
return HighlightSeverity.WARNING;
}
@Nullable
@Override
public String getUnresolvedDescription() {
return null;
}
}
@@ -15,7 +15,6 @@
*/
package com.jetbrains.python.templateLanguages;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -26,10 +25,12 @@ import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelper;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelperRegistrar;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileSystemItemUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.psi.PsiReferenceEx;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.psi.WeakFileReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +39,7 @@ import java.util.Collection;
/**
* @author yole
*/
public class TemplateFileReference extends FileReference implements PsiReferenceEx {
public class TemplateFileReference extends WeakFileReference {
@NotNull private final FileReferenceSet myReferenceSet;
public TemplateFileReference(@NotNull FileReferenceSet fileReferenceSet, TextRange range, int index, String text) {
@@ -46,12 +47,6 @@ public class TemplateFileReference extends FileReference implements PsiReference
myReferenceSet = fileReferenceSet;
}
@Nullable
@Override
public HighlightSeverity getUnresolvedHighlightSeverity(TypeEvalContext context) {
return HighlightSeverity.WARNING;
}
@Nullable
@Override
public String getUnresolvedDescription() {
@@ -1,6 +1,9 @@
package com.jetbrains.python.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiPolyVariantReference;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -27,4 +30,7 @@ public interface PyQualifiedExpression extends PyExpression {
*/
@Nullable
ASTNode getNameElement();
@NotNull
PsiPolyVariantReference getReference(PyResolveContext resolveContext);
}
@@ -30,7 +30,4 @@ public interface PyReferenceExpression extends PyQualifiedExpression, PyReferenc
@NotNull
PsiPolyVariantReference getReference();
@NotNull
PsiPolyVariantReference getReference(PyResolveContext resolveContext);
}
+1
View File
@@ -7,6 +7,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="util" />
</component>
</module>
+13
View File
@@ -0,0 +1,13 @@
package icons;
import com.intellij.openapi.util.IconLoader;
import javax.swing.*;
/**
* NOTE THIS FILE IS AUTO-GENERATED by the build/scripts/icons.gant
* Don't repeat mistakes of others ;-)
*/
public class RestIcons {
public static final Icon Rst = IconLoader.getIcon("/com/jetbrains/rest/res/rst.png"); // 16x16
}
@@ -455,6 +455,7 @@
<configurationProducer implementation="com.jetbrains.django.testRunner.DjangoTestsConfigurationProducer"/>
<highlightErrorFilter implementation="com.jetbrains.django.lang.template.inspection.DjangoErrorFilter"/>
<highlightErrorFilter implementation="com.jetbrains.django.lang.template.inspection.DjangoStructureXmlFilter"/>
<lang.parserDefinition language="DjangoTemplate"
implementationClass="com.jetbrains.django.lang.template.parsing.DjangoTemplateParserDefinition"/>
@@ -97,6 +97,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
/**
* Generates a <code>sys.path[0:0] = [...]</code> with paths that buildout script wants.
*
* @param module to get a buildout facet from
* @return the statement, or null if there's no buildout facet.
*/
@@ -158,7 +159,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
}
return paths;
}
catch(IOException e) {
catch (IOException e) {
LOG.info(e);
return null;
}
@@ -208,18 +209,20 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
String text = VfsUtil.loadText(vFile);
String[] lines = LineTokenizer.tokenize(text, false);
int index = 0;
while(index < lines.length && !lines [index].startsWith("def addsitepackages("))
while (index < lines.length && !lines[index].startsWith("def addsitepackages(")) {
index++;
while(index < lines.length && !lines [index].trim().startsWith("buildout_paths = ["))
}
while (index < lines.length && !lines[index].trim().startsWith("buildout_paths = [")) {
index++;
}
index++;
while(index < lines.length && !lines [index].trim().equals("]")) {
String line = lines [index].trim();
while (index < lines.length && !lines[index].trim().equals("]")) {
String line = lines[index].trim();
if (line.endsWith(",")) {
line = line.substring(0, line.length()-1);
line = line.substring(0, line.length() - 1);
}
if (line.startsWith("'") && line.endsWith("'")) {
result.add(StringUtil.unescapeStringCharacters(line.substring(1, line.length()-1)));
result.add(StringUtil.unescapeStringCharacters(line.substring(1, line.length() - 1)));
}
index++;
}
@@ -243,10 +246,12 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
// alter execution script
ParamsGroup script_params = params.getParamsGroup(PythonCommandLineState.GROUP_SCRIPT);
assert script_params != null;
String normal_script = script_params.getParameters().get(0); // expect DjangoUtil.MANAGE_FILE
String engulfer_path = PythonHelpersLocator.getHelperPath("pycharm/buildout_engulfer.py");
new_env.put("PYCHARM_ENGULF_SCRIPT", getConfiguration().getScriptName());
script_params.getParametersList().replaceOrPrepend(normal_script, engulfer_path);
if (script_params.getParameters().size() > 0) {
String normal_script = script_params.getParameters().get(0); // expect DjangoUtil.MANAGE_FILE
String engulfer_path = PythonHelpersLocator.getHelperPath("pycharm/buildout_engulfer.py");
new_env.put("PYCHARM_ENGULF_SCRIPT", getConfiguration().getScriptName());
script_params.getParametersList().replaceOrPrepend(normal_script, engulfer_path);
}
// add pycharm helpers to pythonpath so that fixGetpass is importable
PythonEnvUtil.addToPythonPath(new_env, PythonHelpersLocator.getHelpersRoot().getAbsolutePath());
@@ -280,7 +285,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
String text = FileUtil.loadFile(cfg);
final PsiFile configFile = PsiFileFactory
.getInstance(getModule().getProject()).createFileFromText("buildout.cfg",
BuildoutCfgLanguage.INSTANCE, text);
BuildoutCfgLanguage.INSTANCE, text);
if (configFile != null && configFile instanceof BuildoutCfgFile) {
return (BuildoutCfgFile)configFile;
}
@@ -290,7 +295,7 @@ public class BuildoutFacet extends Facet<BuildoutFacetConfiguration> implements
}
return null;
}
public static List<File> getScripts(@Nullable BuildoutFacet buildoutFacet, final VirtualFile baseDir) {
File rootPath = null;
if (buildoutFacet != null) {
@@ -1,7 +1,6 @@
package com.jetbrains.python.buildout.config;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
@@ -6,9 +6,11 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.psi.PyParameter;
import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.PyReferenceExpression;
import com.jetbrains.python.psi.PyTargetExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.QualifiedResolveResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,12 +31,15 @@ public class PyTargetElementEvaluator implements TargetElementEvaluator {
}
final PsiElement element = ref.getElement();
PsiElement result = ref.resolve();
if (result instanceof PyReferenceExpression &&
PsiTreeUtil.getParentOfType(element, ScopeOwner.class) == PsiTreeUtil.getParentOfType(result, ScopeOwner.class)) {
QualifiedResolveResult resolveResult = ((PyReferenceExpression)result).followAssignmentsChain(PyResolveContext.noImplicits());
PsiElement finalResult = resolveResult.getElement();
if (PsiTreeUtil.getParentOfType(element, ScopeOwner.class) == PsiTreeUtil.getParentOfType(finalResult, ScopeOwner.class)) {
return finalResult;
while (result instanceof PyReferenceExpression || result instanceof PyTargetExpression) {
PsiElement nextResult = ((PyQualifiedExpression) result).getReference(PyResolveContext.noImplicits()).resolve();
if (nextResult != null && nextResult != result &&
PsiTreeUtil.getParentOfType(element, ScopeOwner.class) == PsiTreeUtil.getParentOfType(result, ScopeOwner.class) &&
(nextResult instanceof PyReferenceExpression || nextResult instanceof PyTargetExpression || nextResult instanceof PyParameter)) {
result = nextResult;
}
else {
break;
}
}
return result;
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Document;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.*;
@@ -50,12 +51,12 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
final ASTNode ctxNode = context.getNode();
if (ctxNode != null && PyTokenTypes.STRING_NODES.contains(ctxNode.getElementType())) return false; // no sense inside string
PsiElement p = (PsiElement)element;
int first_offset = p.getTextOffset();
int firstOffset = p.getTextRange().getStartOffset();
// we must be a stmt ourselves, not a part of another stmt
// try to climb to the stmt level with the same offset
while (true) {
if (p == null) return false;
if (p.getTextOffset() != first_offset) return false;
if (p.getTextRange().getStartOffset() != firstOffset) return false;
if (p instanceof PyStatement) break;
p = p.getParent();
}
@@ -72,7 +73,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
PsiDocumentManager docMgr = PsiDocumentManager.getInstance(p.getProject());
Document doc = docMgr.getDocument(p.getContainingFile().getOriginalFile());
if (doc != null) {
if (doc.getLineNumber(prev.getTextRange().getEndOffset()) == doc.getLineNumber(first_offset)) {
if (doc.getLineNumber(prev.getTextRange().getEndOffset()) == doc.getLineNumber(firstOffset)) {
return false; // same line
}
}
@@ -214,6 +215,9 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
private static final PsiElementPattern.Capture<PsiElement> IN_STRING_LITERAL =
psiElement().inside(PyStringLiteralExpression.class);
private static final PsiElementPattern.Capture<PsiElement> IN_FUNCTION_HEADER =
psiElement().inside(PyFunction.class).andNot(psiElement().inside(PyStatementList.class));
public static final PsiElementPattern.Capture<PsiElement> AFTER_QUALIFIER =
psiElement().afterLeaf(psiElement().withText(".").inside(PyReferenceExpression.class));
@@ -229,12 +233,13 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
psiElement().withElementType(PyTokenTypes.DOT))
).inside(PyFromImportStatement.class);
private static final PsiElementPattern.Capture<PsiElement> IN_WITH_AFTER_REF =
psiElement().afterLeaf(psiElement()
.withElementType(PyTokenTypes.IDENTIFIER)
.inside(PyReferenceExpression.class)
.inside(PyWithStatement.class)
);
public static final ElementPattern<PsiElement> IN_WITH_AFTER_REF =
psiElement().afterLeaf(psiElement().inside(psiElement(PyWithItem.class).with(new PatternCondition<PyWithItem>("withoutAsKeyword") {
@Override
public boolean accepts(@NotNull PyWithItem item, ProcessingContext context) {
return item.getNode().findChildByType(PyTokenTypes.AS_KEYWORD) == null;
}
})));
private static final PsiElementPattern.Capture<PsiElement> IN_EXCEPT_AFTER_REF =
psiElement().afterLeaf(psiElement()
@@ -509,6 +514,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.andNot(IN_PARAM_LIST)
.andNot(IN_FUNCTION_HEADER)
.andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
,
new PyKeywordCompletionProvider("not", "lambda")
@@ -524,6 +530,7 @@ public class PyKeywordCompletionContributor extends CompletionContributor {
.andNot(IN_IMPORT_STMT)
.and(NOT_PARAMETER_OR_DEFAULT_VALUE)
.andNot(AFTER_QUALIFIER)
.andNot(IN_FUNCTION_HEADER)
,
new PyKeywordCompletionProvider(TailType.NONE, "True", "False", "None")
);
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PythonHelpersLocator;
import com.jetbrains.python.documentation.StructuredDocString;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
@@ -15,6 +16,7 @@ import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -249,7 +251,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
final String name = level.isPy3K() ? "StdlibTypes3" : "StdlibTypes2";
if (result.isEmpty()) {
try {
final InputStream s = getClass().getResourceAsStream(String.format("%s.properties", name));
final InputStream s = new FileInputStream(PythonHelpersLocator.getHelperFile(String.format("%s.properties", name)));
try {
result.load(s);
}
@@ -221,7 +221,7 @@ public class PydevConsoleCommunication extends AbstractConsoleCommunication impl
lock.wait(10);
}
catch (InterruptedException e) {
LOG.error(e);
//pass
}
}
}
@@ -17,11 +17,9 @@ import java.util.List;
* @author traff
*/
public class PyClassTreeChooserDialog extends AbstractTreeClassChooserDialog<PyClass>{
public PyClassTreeChooserDialog(String title,
Project project,
GlobalSearchScope scope,
@Nullable Filter<PyClass> classFilter, @Nullable PyClass initialClass) {
super(title, project, scope, classFilter, initialClass);
public PyClassTreeChooserDialog(String title, Project project, GlobalSearchScope scope, @Nullable Filter<PyClass> classFilter,
@Nullable PyClass initialClass) {
super(title, project, scope, PyClass.class, classFilter, initialClass);
}
@NotNull
@@ -38,10 +38,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static javax.swing.SwingUtilities.invokeLater;
@@ -61,7 +58,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
private final Map<String, XBreakpoint<? extends ExceptionBreakpointProperties>> myRegisteredExceptionBreakpoints =
new ConcurrentHashMap<String, XBreakpoint<? extends ExceptionBreakpointProperties>>();
private final List<PyThreadInfo> mySuspendedThreads = Lists.newArrayList();
private final List<PyThreadInfo> mySuspendedThreads = Collections.synchronizedList(Lists.<PyThreadInfo>newArrayList());
private final Map<String, XValueChildrenList> myStackFrameCache = Maps.newHashMap();
private final Map<String, PyDebugValue> myNewVariableValue = Maps.newHashMap();
@@ -46,15 +46,17 @@ public class PyDebuggerEditorsProvider extends XDebuggerEditorsProvider {
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (psiFile != null) {
int offset = sourcePosition.getOffset();
final int lineEndOffset = document.getLineEndOffset(document.getLineNumber(offset));
do {
PsiElement element = psiFile.findElementAt(offset);
if (element != null && !(element instanceof PsiWhiteSpace || element instanceof PsiComment)) {
return PyPsiUtils.getStatement(element);
if (offset >= 0 && offset < document.getTextLength()) {
final int lineEndOffset = document.getLineEndOffset(document.getLineNumber(offset));
do {
PsiElement element = psiFile.findElementAt(offset);
if (element != null && !(element instanceof PsiWhiteSpace || element instanceof PsiComment)) {
return PyPsiUtils.getStatement(element);
}
offset = element.getTextRange().getEndOffset() + 1;
}
offset = element.getTextRange().getEndOffset() + 1;
while (offset < lineEndOffset);
}
while (offset < lineEndOffset);
}
}
return null;
@@ -141,7 +141,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager {
try {
data = CALL_SIGNATURES_ATTRIBUTE.readAttributeBytes(file);
}
catch (IOException e) {
catch (Exception e) {
data = null;
}
@@ -8,6 +8,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyDocStringOwner;
import com.jetbrains.python.psi.PyImportElement;
import com.jetbrains.python.psi.PyStringLiteralExpression;
import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
import com.jetbrains.python.psi.types.PyType;
@@ -85,7 +86,7 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
final PyTypeParser.ParseResult parseResult = PyTypeParser.parse(anchor, s.toString());
final Map<TextRange, PyType> types = parseResult.getTypes();
if (types.isEmpty()) {
result.add(new DocStringTypeReference(anchor, s.getTextRange().shiftRight(offset), s.getTextRange().shiftRight(offset), null));
result.add(new DocStringTypeReference(anchor, s.getTextRange().shiftRight(offset), s.getTextRange().shiftRight(offset), null, null));
}
offset = s.getTextRange().getStartOffset() + offset;
final Map<PyType, TextRange> fullRanges = parseResult.getFullRanges();
@@ -93,7 +94,8 @@ public class DocStringReferenceProvider extends PsiReferenceProvider {
final PyType t = pair.getValue();
final TextRange range = pair.getKey().shiftRight(offset);
final TextRange fullRange = fullRanges.containsKey(t) ? fullRanges.get(t).shiftRight(offset) : range;
result.add(new DocStringTypeReference(anchor, range, fullRange, t));
final PyImportElement importElement = parseResult.getImports().get(t);
result.add(new DocStringTypeReference(anchor, range, fullRange, t, importElement));
}
return result;
}
@@ -6,29 +6,36 @@ import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyImportedModule;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.impl.ResolveResultList;
import com.jetbrains.python.psi.resolve.ImportedResolveResult;
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* User : catherine
*/
public class DocStringTypeReference extends PsiReferenceBase<PsiElement> {
private PyType myType;
private TextRange myFullRange;
public class DocStringTypeReference extends PsiPolyVariantReferenceBase<PsiElement> {
@Nullable private PyType myType;
@NotNull private TextRange myFullRange;
@Nullable private final PyImportElement myImportElement;
public DocStringTypeReference(PsiElement element, TextRange range, TextRange fullRange, @Nullable PyType type) {
public DocStringTypeReference(PsiElement element, TextRange range, @NotNull TextRange fullRange, @Nullable PyType type,
@Nullable PyImportElement importElement) {
super(element, range);
myFullRange = fullRange;
myType = type;
myImportElement = importElement;
}
@Nullable
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element.equals(resolve())) {
@@ -49,7 +56,7 @@ public class DocStringTypeReference extends PsiReferenceBase<PsiElement> {
}
public boolean isSoft() {
return true;
return false;
}
@Override
@@ -68,16 +75,28 @@ public class DocStringTypeReference extends PsiReferenceBase<PsiElement> {
return super.isReferenceTo(element);
}
@Nullable
public PsiElement resolve() {
@NotNull
@Override
public ResolveResult[] multiResolve(boolean incompleteCode) {
PsiElement result = null;
final ResolveResultList results = new ResolveResultList();
if (myType instanceof PyClassType) {
return ((PyClassType)myType).getPyClass();
result = ((PyClassType)myType).getPyClass();
}
if (myType instanceof PyImportedModuleType) {
final PyImportedModule module = ((PyImportedModuleType)myType).getImportedModule();
return module.resolve();
else if (myType instanceof PyImportedModuleType) {
result = ((PyImportedModuleType)myType).getImportedModule().resolve();
}
return null;
if (result != null) {
if (myImportElement != null) {
results.add(new ImportedResolveResult(result,
RatedResolveResult.RATE_NORMAL,
Collections.<PsiElement>singletonList(myImportElement)));
}
else {
results.poke(result, RatedResolveResult.RATE_NORMAL);
}
}
return results.toArray(new ResolveResult[0]);
}
@NotNull
@@ -36,6 +36,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
@@ -385,16 +386,22 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
}
private static boolean pageExists(String url) {
if (new File(url).exists()) {
return true;
}
HttpClient client = new HttpClient();
client.setTimeout(5 * 1000);
client.setConnectionTimeout(5 * 1000);
HeadMethod method = new HeadMethod(url);
try {
HeadMethod method = new HeadMethod(url);
int rc = client.executeMethod(method);
if (rc == 404) {
return false;
}
}
catch (IllegalArgumentException e) {
return false;
}
catch (IOException ignored) {
}
return true;
@@ -4,12 +4,16 @@ import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.FindUsagesHandlerFactory;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyImportedModule;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
@@ -22,14 +26,22 @@ public class PyFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
@Override
public boolean canFindUsages(@NotNull PsiElement element) {
return element instanceof PyClass ||
(element instanceof PyFile && PyNames.INIT_DOT_PY.equals(((PyFile) element).getName())) ||
(element instanceof PyFile && PyUtil.isPackage((PyFile)element)) ||
element instanceof PyImportedModule ||
element instanceof PyFunction;
}
@Nullable
@Override
public FindUsagesHandler createFindUsagesHandler(@NotNull PsiElement element, boolean forHighlightUsages) {
if (element instanceof PyFile) {
return new PyModuleFindUsagesHandler((PyFile) element);
if (element instanceof PyImportedModule) {
final PsiElement resolved = ((PyImportedModule)element).resolve();
if (resolved != null) {
element = resolved;
}
}
if (element instanceof PsiFileSystemItem) {
return new PyModuleFindUsagesHandler((PsiFileSystemItem)element);
}
if (element instanceof PyFunction) {
if (!forHighlightUsages) {
@@ -60,7 +72,10 @@ public class PyFindUsagesHandlerFactory extends FindUsagesHandlerFactory {
}
return new PyFunctionFindUsagesHandler(element);
}
return new PyClassFindUsagesHandler((PyClass)element);
if (element instanceof PyClass) {
return new PyClassFindUsagesHandler((PyClass)element);
}
return null;
}
private static boolean isInClassobj(PyFunction fun) {
@@ -8,7 +8,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyUtil;
import org.jetbrains.annotations.NotNull;
@@ -18,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
public class PyModuleFindUsagesHandler extends FindUsagesHandler {
private final PsiFileSystemItem myElement;
protected PyModuleFindUsagesHandler(@NotNull PyFile file) {
protected PyModuleFindUsagesHandler(@NotNull PsiFileSystemItem file) {
super(file);
final PsiElement e = PyUtil.turnInitIntoDir(file);
myElement = e instanceof PsiFileSystemItem ? (PsiFileSystemItem)e : file;
@@ -39,6 +39,7 @@ import com.jetbrains.python.codeInsight.imports.OptimizeImportsQuickFix;
import com.jetbrains.python.codeInsight.imports.PythonReferenceImporter;
import com.jetbrains.python.console.PydevConsoleRunner;
import com.jetbrains.python.documentation.DocStringParameterReference;
import com.jetbrains.python.documentation.DocStringTypeReference;
import com.jetbrains.python.packaging.PyPIPackageUtil;
import com.jetbrains.python.packaging.PyPackageManager;
import com.jetbrains.python.packaging.PyRequirement;
@@ -366,6 +367,9 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
private void registerUnresolvedReferenceProblem(@NotNull PyElement node, @NotNull PsiReference reference,
@NotNull HighlightSeverity severity) {
if (reference instanceof DocStringTypeReference) {
return;
}
String description = null;
final String text = reference.getElement().getText();
TextRange rangeInElement = reference.getRangeInElement();
@@ -361,23 +361,6 @@ public class PyUtil {
return superClasses;
}
/**
* Finds the first identifier AST node under target element, and returns its text.
*
* @param target
* @return identifier text, or null.
*/
public static
@Nullable
String getIdentifier(PsiElement target) {
ASTNode node = target.getNode();
if (node != null) {
ASTNode ident_node = node.findChildByType(PyTokenTypes.IDENTIFIER);
if (ident_node != null) return ident_node.getText();
}
return null;
}
// TODO: move to a more proper place?
@@ -392,16 +375,16 @@ public class PyUtil {
if (ref != null) {
PyExpression qualifier = ref.getQualifier();
if (qualifier != null) {
String attr_name = getIdentifier(ref);
if ("__class__".equals(attr_name)) {
PyType qual_type = context.getType(qualifier);
if (qual_type instanceof PyClassType) {
return new PyClassTypeImpl(((PyClassType)qual_type).getPyClass(), true); // always as class, never instance
String attr_name = ref.getReferencedName();
if (PyNames.CLASS.equals(attr_name)) {
PyType qualifierType = context.getType(qualifier);
if (qualifierType instanceof PyClassType) {
return new PyClassTypeImpl(((PyClassType)qualifierType).getPyClass(), true); // always as class, never instance
}
}
else if ("__dict__".equals(attr_name)) {
PyType qual_type = context.getType(qualifier);
if (qual_type instanceof PyClassType && ((PyClassType)qual_type).isDefinition()) {
else if (PyNames.DICT.equals(attr_name)) {
PyType qualifierType = context.getType(qualifier);
if (qualifierType instanceof PyClassType && ((PyClassType)qualifierType).isDefinition()) {
return PyBuiltinCache.getInstance(ref).getDictType();
}
}
@@ -4,7 +4,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.stubs.IStubElementType;
@@ -202,11 +201,7 @@ public class PyImportElementImpl extends PyBaseElementImpl<PyImportElementStub>
}
if (qName.getComponentCount() == 1) {
if (resolveImportElement) {
final PsiElement element = ResolveImportUtil.resolveImportElement(this, PyQualifiedName.fromComponents(name));
if (element instanceof PsiDirectory) {
return createImportedModule(name);
}
return element;
return ResolveImportUtil.resolveImportElement(this, PyQualifiedName.fromComponents(name));
}
return this;
}
@@ -134,7 +134,9 @@ public class PyImportedModule extends LightElement implements NameDefiner {
@Nullable
private static PsiElement resolve(PyImportElement importElement, @NotNull final PyQualifiedName prefix) {
return PyUtil.turnDirIntoInit(ResolveImportUtil.resolveImportElement(importElement, prefix));
final PsiElement resolved = ResolveImportUtil.resolveImportElement(importElement, prefix);
final PsiElement packageInit = PyUtil.turnDirIntoInit(resolved);
return packageInit != null ? packageInit : resolved;
}
public boolean isAncestorOf(PyImportedModule other) {
@@ -5,6 +5,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.search.GlobalSearchScope;
@@ -481,10 +482,15 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
@NotNull
@Override
public PsiReference getReference() {
return getReference(PyResolveContext.defaultContext());
}
@NotNull
public PsiPolyVariantReference getReference(final PyResolveContext resolveContext) {
if (getQualifier() != null) {
return new PyQualifiedReference(this, PyResolveContext.defaultContext());
return new PyQualifiedReference(this, resolveContext);
}
return new PyTargetReference(this, PyResolveContext.defaultContext());
return new PyTargetReference(this, resolveContext);
}
@NotNull
@@ -238,7 +238,7 @@ public class PyQualifiedReference extends PyReferenceImpl {
@NotNull
@Override
public Object[] getVariants() {
PyExpression qualifier = myElement.getQualifier();
PyExpression qualifier = CompletionUtil.getOriginalOrSelf(myElement.getQualifier());
assert qualifier != null;
final PyQualifiedExpression element = CompletionUtil.getOriginalOrSelf(myElement);
@@ -241,7 +241,10 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
for (PsiElement hit : processor.getDefiners()) {
ret.poke(hit, getRate(hit));
}
uexpr = PyUtil.turnDirIntoInit(uexpr); // an import statement may have returned a dir
final PsiElement packageInit = PyUtil.turnDirIntoInit(uexpr);
if (packageInit != null) {
uexpr = packageInit; // an import statement may have returned a dir
}
}
else if (!processor.getDefiners().isEmpty()) {
ret.add(new ImportedResolveResult(null, RatedResolveResult.RATE_LOW, processor.getDefiners()));
@@ -396,9 +399,19 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
if (resolveResult instanceof PyImportedModule) {
resolveResult = resolveResult.getNavigationElement();
}
if (element instanceof PsiDirectory && resolveResult instanceof PyFile &&
PyNames.INIT_DOT_PY.equals(((PyFile)resolveResult).getName()) && ((PyFile)resolveResult).getContainingDirectory() == element) {
return true;
if (element instanceof PsiDirectory) {
if (resolveResult instanceof PyFile) {
final PyFile file = (PyFile)resolveResult;
if (PyUtil.isPackage(file) && file.getContainingDirectory() == element) {
return true;
}
}
else if (resolveResult instanceof PsiDirectory) {
final PsiDirectory directory = (PsiDirectory)resolveResult;
if (PyUtil.isPackage(directory) && directory == element) {
return true;
}
}
}
return resolveResult == element;
}
@@ -40,19 +40,23 @@ public class PyTypeParser {
public static ParseResult parse(@Nullable PsiElement anchor, @NotNull String type) {
final Map<TextRange, PyType> types = new HashMap<TextRange, PyType>();
final Map<PyType, TextRange> fullRanges = new HashMap<PyType, TextRange>();
final PyType t = parse(anchor, type, types, fullRanges, 0);
return new ParseResult(t, types, fullRanges);
final Map<PyType, PyImportElement> imports = new HashMap<PyType, PyImportElement>();
final PyType t = parse(anchor, type, types, fullRanges, imports, 0);
return new ParseResult(t, types, fullRanges, imports);
}
public static class ParseResult {
@Nullable private PyType myType;
@NotNull private Map<TextRange, PyType> myTypes;
@NotNull private Map<PyType, TextRange> myFullRanges;
@NotNull private final Map<PyType, PyImportElement> myImports;
ParseResult(@Nullable PyType type, @NotNull Map<TextRange, PyType> types, @NotNull Map<PyType, TextRange> fullRanges) {
ParseResult(@Nullable PyType type, @NotNull Map<TextRange, PyType> types, @NotNull Map<PyType, TextRange> fullRanges,
@NotNull Map<PyType, PyImportElement> imports) {
myType = type;
myTypes = types;
myFullRanges = fullRanges;
myImports = imports;
}
@Nullable
@@ -69,11 +73,16 @@ public class PyTypeParser {
public Map<PyType, TextRange> getFullRanges() {
return myFullRanges;
}
@NotNull
public Map<PyType, PyImportElement> getImports() {
return myImports;
}
}
@Nullable
private static PyType parse(@Nullable PsiElement anchor, @NotNull String type, @NotNull Map<TextRange, PyType> types,
@NotNull Map<PyType, TextRange> fullRanges, int offset) {
@NotNull Map<PyType, TextRange> fullRanges, @NotNull Map<PyType, PyImportElement> imports, int offset) {
if (anchor == null || !anchor.isValid()) {
return null;
}
@@ -87,10 +96,10 @@ public class PyTypeParser {
return t;
}
if (type.startsWith("(") && type.endsWith(")")) {
return parseTupleType(anchor, type.substring(1, type.length() - 1), types, fullRanges, offset + 1);
return parseTupleType(anchor, type.substring(1, type.length() - 1), types, fullRanges, imports, offset + 1);
}
if (type.contains(" or ")) {
return parseUnionType(anchor, type, types, fullRanges, offset);
return parseUnionType(anchor, type, types, fullRanges, imports, offset);
}
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(anchor);
if (type.equals("unknown")) {
@@ -132,7 +141,7 @@ public class PyTypeParser {
return t;
}
if (type.startsWith("dict from")) {
return parseDictFromToType(anchor, type, types, fullRanges, offset);
return parseDictFromToType(anchor, type, types, fullRanges, imports, offset);
}
if (type.equals("integer") || (type.equals("long") && LanguageLevel.forElement(anchor).isPy3K())) {
final PyType t = builtinCache.getIntType();
@@ -144,8 +153,8 @@ public class PyTypeParser {
}
final Matcher m = PARAMETRIZED_CLASS.matcher(type);
if (m.matches()) {
final PyType objType = parseObjectType(anchor, m.group(1), builtinCache, types, fullRanges, offset + m.start(1));
final PyType elementType = parse(anchor, m.group(2), types, fullRanges, offset + m.start(2));
final PyType objType = parseObjectType(anchor, m.group(1), builtinCache, types, fullRanges, imports, offset + m.start(1));
final PyType elementType = parse(anchor, m.group(2), types, fullRanges, imports, offset + m.start(2));
if (objType != null) {
if (objType instanceof PyClassType && elementType != null) {
return new PyCollectionTypeImpl(((PyClassType)objType).getPyClass(), false, elementType);
@@ -153,12 +162,13 @@ public class PyTypeParser {
return objType;
}
}
return parseObjectType(anchor, type, builtinCache, types, fullRanges, offset);
return parseObjectType(anchor, type, builtinCache, types, fullRanges, imports, offset);
}
@Nullable
private static PyType parseObjectType(@NotNull PsiElement anchor, @NotNull String type, @NotNull PyBuiltinCache builtinCache,
@NotNull Map<TextRange, PyType> types, @NotNull Map<PyType, TextRange> fullRanges, int offset) {
@NotNull Map<TextRange, PyType> types, @NotNull Map<PyType, TextRange> fullRanges,
@NotNull Map<PyType, PyImportElement> imports, int offset) {
final TextRange whole = new TextRange(offset, offset + type.length());
final PyClassType classType = builtinCache.getObjectType(type);
if (classType != null) {
@@ -170,6 +180,7 @@ public class PyTypeParser {
final PyClass aClass = ((PyFile)anchorFile).findTopLevelClass(type);
if (aClass != null) {
final PyType t = new PyClassTypeImpl(aClass, false);
t.assertValid("PyFile.findTopLevelClass()");
types.put(whole, t);
return t;
}
@@ -187,6 +198,7 @@ public class PyTypeParser {
final PyType pyType = getTypeFromQName(anchor, qName, whole, unusedRanges, fullRanges, offset);
if (pyType != null) {
types.put(whole, pyType);
imports.put(pyType, element);
return pyType;
}
}
@@ -199,6 +211,7 @@ public class PyTypeParser {
final Collection<PyClass> classes = PyClassNameIndex.find(type, anchor.getProject(), true);
if (classes.size() == 1) {
final PyType t = new PyClassTypeImpl(classes.iterator().next(), false);
t.assertValid("PyClassNameIndex.find().iterator().next()");
types.put(whole, t);
return t;
}
@@ -237,9 +250,12 @@ public class PyTypeParser {
if (t instanceof PyClassType) {
t = ((PyClassType)t).toInstance();
}
types.put(classRange.shiftRight(offset), t);
fullRanges.put(t, whole);
return t;
if (t != null) {
t.assertValid("PyImportedModuleType.resolveMember()");
types.put(classRange.shiftRight(offset), t);
fullRanges.put(t, whole);
return t;
}
}
}
}
@@ -247,6 +263,7 @@ public class PyTypeParser {
for (PyClass aClass : classes) {
if (qName.equals(aClass.getQualifiedName())) {
final PyType t = new PyClassTypeImpl(aClass, false);
t.assertValid("PyClassNameIndex.find()");
types.put(classRange.shiftRight(offset), t);
fullRanges.put(t, whole);
return t;
@@ -257,6 +274,7 @@ public class PyTypeParser {
final String name = aClass.getQualifiedName();
if (name != null && name.startsWith("_")) {
final PyType t = new PyClassTypeImpl(aClass, false);
t.assertValid("PyClassNameIndex.find() for _foo");
types.put(classRange.shiftRight(offset), t);
fullRanges.put(t, whole);
return t;
@@ -268,24 +286,26 @@ public class PyTypeParser {
@Nullable
private static PyType parseTupleType(@NotNull PsiElement anchor, @NotNull String elementTypeNames, @NotNull Map<TextRange, PyType> types,
@NotNull Map<PyType, TextRange> fullRanges, int offset) {
@NotNull Map<PyType, TextRange> fullRanges, @NotNull Map<PyType, PyImportElement> imports,
int offset) {
final List<TextRange> ranges = splitRanges(elementTypeNames, ",");
final List<PyType> elementTypes = new ArrayList<PyType>();
for (TextRange range : ranges) {
elementTypes.add(parse(anchor, range.substring(elementTypeNames), types, fullRanges, offset + range.getStartOffset()));
elementTypes.add(parse(anchor, range.substring(elementTypeNames), types, fullRanges, imports, offset + range.getStartOffset()));
}
return PyTupleType.create(anchor, elementTypes.toArray(new PyType[elementTypes.size()]));
}
@Nullable
private static PyType parseDictFromToType(@NotNull PsiElement anchor, @NotNull String type, @NotNull Map<TextRange, PyType> types,
@NotNull Map<PyType, TextRange> fullRanges, int offset) {
@NotNull Map<PyType, TextRange> fullRanges, @NotNull Map<PyType, PyImportElement> imports,
int offset) {
final Matcher m = DICT_TYPE.matcher(type);
PyClassType dict = PyBuiltinCache.getInstance(anchor).getDictType();
if (dict != null) {
if (m.matches()) {
PyType from = parse(anchor, m.group(1), types, fullRanges, offset + m.start(1));
PyType to = parse(anchor, m.group(2), types, fullRanges, offset + m.start(2));
PyType from = parse(anchor, m.group(1), types, fullRanges, imports, offset + m.start(1));
PyType to = parse(anchor, m.group(2), types, fullRanges, imports, offset + m.start(2));
final PyType p = PyTupleType.create(anchor, new PyType[] {from, to});
return new PyCollectionTypeImpl(dict.getPyClass(), false, p);
}
@@ -296,11 +316,12 @@ public class PyTypeParser {
@Nullable
private static PyType parseUnionType(@NotNull PsiElement anchor, @NotNull String type, @NotNull Map<TextRange, PyType> types,
@NotNull Map<PyType, TextRange> fullRanges, int offset) {
@NotNull Map<PyType, TextRange> fullRanges, @NotNull Map<PyType, PyImportElement> imports,
int offset) {
final List<TextRange> ranges = splitRanges(type, " or ");
PyType result = null;
for (TextRange range : ranges) {
final PyType t = parse(anchor, range.substring(type), types, fullRanges, offset + range.getStartOffset());
final PyType t = parse(anchor, range.substring(type), types, fullRanges, imports, offset + range.getStartOffset());
result = (result == null) ? t : PyUnionType.union(result, t);
}
return result;
@@ -199,7 +199,7 @@ public class PySkeletonGenerator {
return new ListBinariesResult(generatorVersion, binaries);
}
public boolean deleteOrLog(File item) {
public boolean deleteOrLog(@NotNull File item) {
boolean deleted = item.delete();
if (!deleted) LOG.warn("Failed to delete skeleton file " + item.getAbsolutePath());
return deleted;
@@ -0,0 +1,4 @@
class Foo(object):
xyzzy = 3
def fun(self):
a = self.__class__.xyzzy
@@ -0,0 +1,4 @@
class Foo(object):
xyzzy = 3
def fun(self):
a = self.__class__.x<caret>
@@ -0,0 +1,3 @@
import nspkg1.m1
print(ns<caret>pkg1)
@@ -0,0 +1 @@
import nspkg1
@@ -0,0 +1,7 @@
from datetime import timedelta #pass
def f(d):
"""
:type d: timedelta or int
"""
pass
@@ -0,0 +1,6 @@
def cover(a, lab=1):
item = a + lab
lab = 1
if a > 1:
lab = cover(item, lab)
return l<caret>ab
@@ -0,0 +1,6 @@
def cover(a, bar=1):
item = a + bar
bar = 1
if a > 1:
bar = cover(item, bar)
return bar
@@ -0,0 +1,3 @@
def lab(): pass
lab = 1
print(l<caret>ab)
@@ -0,0 +1,3 @@
def lab(): pass
bar = 1
print(bar)
@@ -1,7 +1,11 @@
package com.jetbrains.python;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.usageView.UsageInfo;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.LanguageLevel;
import java.util.*;
@@ -111,4 +115,26 @@ public class PyFindUsagesTest extends PyTestCase {
"<caret>testMethod = staticmethod(testMethod)",
"testMethod = staticmethod(<caret>testMethod)");
}
// PY-7348
public void testNamespacePackageUsages() {
setLanguageLevel(LanguageLevel.PYTHON33);
try {
final Collection<UsageInfo> usages = findMultiFileUsages("a.py");
assertEquals(3, usages.size());
} finally {
setLanguageLevel(null);
}
}
private Collection<UsageInfo> findMultiFileUsages(String filename) {
final String testName = getTestName(false);
myFixture.copyDirectoryToProject("findUsages/" + testName, "");
PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments();
myFixture.configureFromTempProjectFile(filename);
final int flags = TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED;
final PsiElement element = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), flags);
assertNotNull(element);
return myFixture.findUsages(element);
}
}
@@ -9,7 +9,6 @@ import com.jetbrains.cython.psi.CythonFunction;
import com.jetbrains.cython.psi.CythonVariable;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyImportedModule;
/**
* @author yole
@@ -364,10 +363,7 @@ public class PyMultiFileResolveTest extends PyResolveTestCase {
// PY-2813
public void testNamespacePackage() {
final PsiElement element = doResolve();
assertInstanceOf(element, PyImportedModule.class);
final PyImportedModule module = (PyImportedModule)element;
assertEquals("p1", module.getImportedPrefix().toString());
assertResolvesTo(PsiDirectory.class, "p1");
}
// PY-2813
@@ -408,10 +404,7 @@ public class PyMultiFileResolveTest extends PyResolveTestCase {
public void testPython33NamespacePackage() {
setLanguageLevel(LanguageLevel.PYTHON33);
try {
final PsiElement element = doResolve();
assertInstanceOf(element, PyImportedModule.class);
final PyImportedModule module = (PyImportedModule)element;
assertEquals("p1", module.getImportedPrefix().toString());
assertResolvesTo(PsiDirectory.class, "p1");
} finally {
setLanguageLevel(null);
}
@@ -591,9 +591,13 @@ public class PythonCompletionTest extends PyTestCase {
doTest();
}
public void testDunderClass() { // PY-7327
doTest();
}
public void testAsInWith() { // PY-3701
setLanguageLevel(LanguageLevel.PYTHON27);
assertTrue(doTestByText("with foo <caret>").contains("as"));
assertTrue(doTestByText("with open(foo) <caret>").contains("as"));
}
public void testAsInExcept() { // PY-1846
@@ -1,25 +1,33 @@
package com.jetbrains.python.codeInsight;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.codeInsight.completion.PyKeywordCompletionContributor;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.LanguageLevel;
/**
* @author yole
*/
public class PyCompletionPatternsTest extends PyTestCase {
public void testInFromImportAfterRef() {
String text = "from . im";
myFixture.configureByText(PythonFileType.INSTANCE, text);
PsiElement element = myFixture.getFile().findElementAt(text.length() - 1);
assertTrue(PyKeywordCompletionContributor.IN_FROM_IMPORT_AFTER_REF.accepts(element));
assertTrue(doTest("from . im", PyKeywordCompletionContributor.IN_FROM_IMPORT_AFTER_REF));
}
public void testAfterQualifier() {
String text = "from . im";
assertFalse(doTest("from . im", PyKeywordCompletionContributor.AFTER_QUALIFIER));
}
public void testWith() {
setLanguageLevel(LanguageLevel.PYTHON27);
assertTrue(doTest("with open(foo) ", PyKeywordCompletionContributor.IN_WITH_AFTER_REF));
assertFalse(doTest("with open(foo) as ", PyKeywordCompletionContributor.IN_WITH_AFTER_REF));
}
private boolean doTest(final String text, final ElementPattern<PsiElement> ref) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
PsiElement element = myFixture.getFile().findElementAt(text.length() - 1);
assertFalse(PyKeywordCompletionContributor.AFTER_QUALIFIER.accepts(element));
return ref.accepts(element);
}
}
@@ -185,6 +185,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
// PY-7315
public void testImportUsedInDocString() {
doTest();
}
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
@@ -91,6 +91,14 @@ public class PyRenameTest extends PyTestCase {
doTest("bar");
}
public void testRenameReassignedParameter() { // PY-3698
doTest("bar");
}
public void testRenameShadowingVariable() { // PY-7342
doTest("bar");
}
public void testRenameProperty() { // PY-5948
setLanguageLevel(LanguageLevel.PYTHON26);
try {