mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
+6
-11
@@ -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);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
+16
-9
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user