From dc246da8157453476012d491e9d0506026e02189 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 4 Feb 2013 20:31:42 +0100 Subject: [PATCH 01/54] Fixed time import. --- python/helpers/generator3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index ec4879dfe850..0ae7b6e1aa9e 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -2468,12 +2468,12 @@ if sys.platform == 'cli': def elapsed(self): return (DateTime.Now - self.started).TotalMilliseconds else: - from time import time + import time class Timer(object): def __init__(self): - self.started = time() + self.started = time.time() def elapsed(self): - return int((time() - self.started)*1000) + return int((time.time() - self.started)*1000) # command-line interface From 165a805e0f42a4ecf9539ea5bfbe38f2a26d920c Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Tue, 5 Feb 2013 21:01:11 +0400 Subject: [PATCH 02/54] Use cache in TypeEvalContext when choosing left/right binary operator (PY-8731) --- python/src/com/jetbrains/python/psi/types/PyTypeChecker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 8c3caf7f37b1..8157c052f6dc 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -352,7 +352,7 @@ public class PyTypeChecker { final PsiElement resolved = result.getElement(); if (resolved instanceof PyTypedElement) { final PyTypedElement typedElement = (PyTypedElement)resolved; - final PyType type = typedElement.getType(context); + final PyType type = context.getType(typedElement); if (!(type instanceof PyFunctionType)) { return null; } @@ -370,7 +370,7 @@ public class PyTypeChecker { if (firstResults == null) { firstResults = results; } - if (match(param.getType(context), arg.getType(context), context)) { + if (match(context.getType(param), context.getType(arg), context)) { return results; } } From a9bb526c227b242afc1bbdc5a8d195b889a8ec88 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Tue, 5 Feb 2013 22:06:52 +0400 Subject: [PATCH 03/54] Added TypeEvalContext.Key to PyTypedElement.getType to statically force type evaluation via TypeEvalContext only --- .../python/codeInsight/PyDynamicMember.java | 2 +- .../jetbrains/python/psi/PyTypedElement.java | 2 +- .../python/psi/types/PyTypeProviderBase.java | 2 +- .../python/psi/types/TypeEvalContext.java | 8 +++++- .../PyDictKeyNamesCompletionContributor.java | 2 +- .../ImportFromToImportIntention.java | 2 +- ...DictConstructorToLiteralFormIntention.java | 2 +- ...yStringConcatenationToFormatIntention.java | 2 +- .../intentions/TypeAssertionIntention.java | 2 +- .../codeInsight/intentions/TypeIntention.java | 3 ++- .../stdlib/PyStdlibTypeProvider.java | 6 ++--- .../documentation/DocStringTypeReference.java | 2 +- .../documentation/PyDocumentationBuilder.java | 4 +-- .../documentation/PyTypeModelBuilder.java | 2 +- .../PythonDocumentationProvider.java | 6 ++--- .../findUsages/PyUsageTypeProvider.java | 2 +- .../PyAugmentAssignmentInspection.java | 2 +- .../PyBroadExceptionInspection.java | 4 +-- .../PyCallingNonCallableInspection.java | 4 +-- .../PyPropertyDefinitionInspection.java | 2 +- .../inspections/PyStringFormatInspection.java | 2 +- .../PySuperArgumentsInspection.java | 2 +- .../PyTupleAssignmentBalanceInspection.java | 2 +- .../inspections/PyTypeCheckerInspection.java | 4 +-- .../PyUnresolvedReferencesInspection.java | 6 ++--- .../quickfix/AddMethodQuickFix.java | 2 +- .../src/com/jetbrains/python/psi/PyUtil.java | 2 +- .../psi/impl/PyBinaryExpressionImpl.java | 2 +- .../psi/impl/PyBoolLiteralExpressionImpl.java | 2 +- .../psi/impl/PyCallExpressionHelper.java | 4 +-- .../python/psi/impl/PyCallExpressionImpl.java | 2 +- .../python/psi/impl/PyClassImpl.java | 4 +-- .../psi/impl/PyConditionalExpressionImpl.java | 2 +- .../python/psi/impl/PyDecoratorImpl.java | 2 +- .../psi/impl/PyDictCompExpressionImpl.java | 2 +- .../psi/impl/PyDictLiteralExpressionImpl.java | 2 +- .../psi/impl/PyEmptyExpressionImpl.java | 2 +- .../jetbrains/python/psi/impl/PyFileImpl.java | 2 +- .../python/psi/impl/PyFunctionImpl.java | 6 ++--- .../psi/impl/PyGeneratorExpressionImpl.java | 4 +-- .../psi/impl/PyKeyValueExpressionImpl.java | 6 ++--- .../psi/impl/PyKeywordArgumentImpl.java | 4 +-- .../psi/impl/PyLambdaExpressionImpl.java | 4 +-- .../psi/impl/PyListCompExpressionImpl.java | 4 +-- .../psi/impl/PyListLiteralExpressionImpl.java | 2 +- .../python/psi/impl/PyNamedParameterImpl.java | 2 +- .../psi/impl/PyNoneLiteralExpressionImpl.java | 2 +- .../impl/PyNumericLiteralExpressionImpl.java | 2 +- .../impl/PyParenthesizedExpressionImpl.java | 2 +- .../psi/impl/PyPrefixExpressionImpl.java | 2 +- .../psi/impl/PyReferenceExpressionImpl.java | 2 +- .../python/psi/impl/PyReprExpressionImpl.java | 2 +- .../psi/impl/PySetCompExpressionImpl.java | 2 +- .../psi/impl/PySetLiteralExpressionImpl.java | 2 +- .../psi/impl/PySliceExpressionImpl.java | 2 +- .../python/psi/impl/PyStarArgumentImpl.java | 2 +- .../python/psi/impl/PyStarExpressionImpl.java | 2 +- .../impl/PyStringLiteralExpressionImpl.java | 2 +- .../impl/PySubscriptionExpressionImpl.java | 2 +- .../psi/impl/PyTargetExpressionImpl.java | 12 ++++----- .../psi/impl/PyTupleExpressionImpl.java | 2 +- .../psi/impl/PyYieldExpressionImpl.java | 4 +-- .../impl/references/PyImportReference.java | 4 +-- .../impl/references/PyQualifiedReference.java | 4 +-- .../python/psi/types/PyClassTypeImpl.java | 7 ++--- .../psi/types/PyLiteralCollectionType.java | 2 +- .../python/psi/types/PyTypeChecker.java | 10 +++---- .../python/psi/types/PyTypeParser.java | 2 +- .../refactoring/PyReplaceExpressionUtil.java | 2 +- .../introduce/IntroduceHandler.java | 2 +- .../com/jetbrains/python/PyTypeTest.java | 26 +++++++++---------- 71 files changed, 125 insertions(+), 117 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java b/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java index a7a87892fe77..3e5e117a30eb 100644 --- a/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java +++ b/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java @@ -177,7 +177,7 @@ public class PyDynamicMember { myContext = context; } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { if (myTypeCallback != null) { return myTypeCallback.fun(myContext); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyTypedElement.java b/python/psi-api/src/com/jetbrains/python/psi/PyTypedElement.java index aedbf201152b..deeba1b60c19 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyTypedElement.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyTypedElement.java @@ -12,5 +12,5 @@ import org.jetbrains.annotations.Nullable; */ public interface PyTypedElement extends PyElement { @Nullable - PyType getType(@NotNull TypeEvalContext context); + PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java index ed347a8183df..81988147bd01 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java @@ -37,7 +37,7 @@ public class PyTypeProviderBase implements PyTypeProvider { final ReturnTypeCallback typeCallback = myStringToReturnTypeMap.get(containingClass.getQualifiedName()); if (typeCallback != null) { final PyExpression qualifier = callSite != null ? callSite.getQualifier() : null; - PyType qualifierType = qualifier != null ? qualifier.getType(context) : null; + PyType qualifierType = qualifier != null ? context.getType(qualifier) : null; return typeCallback.getType(callSite, qualifierType, context); } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java index 36de8388619b..ea5844ecc62b 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java @@ -14,6 +14,12 @@ import java.util.*; * @author yole */ public class TypeEvalContext { + public static class Key { + private static final Key INSTANCE = new Key(); + + private Key() {} + } + private final boolean myAllowDataFlow; private final boolean myAllowStubToAST; private List myTrace; @@ -116,7 +122,7 @@ public class TypeEvalContext { } evaluating.add(element); try { - PyType result = element.getType(this); + PyType result = element.getType(this, Key.INSTANCE); if (result != null) { result.assertValid(element.toString()); } diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java index 27661b25a1d4..ee5c6a315ac8 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PyDictKeyNamesCompletionContributor.java @@ -115,7 +115,7 @@ public class PyDictKeyNamesCompletionContributor extends CompletionContributor { final String name = callee.getText(); if ("dict".equals(name)) { final TypeEvalContext context = TypeEvalContext.fast(); - final PyType type = dictConstructor.getType(context); + final PyType type = context.getType(dictConstructor); if (type != null && type.isBuiltin(context)) { final PyArgumentList list = dictConstructor.getArgumentList(); if (list == null) return; diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/ImportFromToImportIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/ImportFromToImportIntention.java index 875ca8ed89bd..bb881905c74b 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/ImportFromToImportIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/ImportFromToImportIntention.java @@ -141,7 +141,7 @@ public class ImportFromToImportIntention implements IntentionAction { PyReferenceExpression ref = import_element.getImportReferenceExpression(); if (ref != null && ref.isValid()) { PsiElement target = ref.getReference().resolve(); - if (target instanceof PyExpression && ((PyExpression)target).getType(TypeEvalContext.fast()) instanceof PyModuleType) return false; + if (target instanceof PyExpression && TypeEvalContext.fast().getType((PyExpression)target) instanceof PyModuleType) return false; } } diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java index 7bacf03016af..34634a3e03f3 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictConstructorToLiteralFormIntention.java @@ -38,7 +38,7 @@ public class PyDictConstructorToLiteralFormIntention extends BaseIntentionAction if (expression != null && expression.isCalleeText("dict")) { final TypeEvalContext context = TypeEvalContext.fast(); - PyType type = expression.getType(context); + PyType type = context.getType(expression); if (type != null && type.isBuiltin(context)) { PyExpression[] argumentList = expression.getArguments(); for (PyExpression argument : argumentList) { diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java index b57ea1d698f2..690207bcb9f5 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java @@ -62,7 +62,7 @@ public class PyStringConcatenationToFormatIntention extends BaseIntentionAction } if (expression instanceof PyStringLiteralExpression) continue; - final PyType type = expression.getType(TypeEvalContext.fastStubOnly(file)); + final PyType type = TypeEvalContext.fastStubOnly(file).getType(expression); final boolean isStringReference = PyTypeChecker.match(cache.getStringType(LanguageLevel.forElement(expression)), type, TypeEvalContext.fastStubOnly(file)) && type != null; if (!isStringReference) { diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java index 324cbca8b755..1dc1d8ca8309 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java @@ -59,7 +59,7 @@ public class TypeAssertionIntention implements IntentionAction { (reference != null && reference.resolve() == null)) { return false; } - final PyType type = problemElement.getType(TypeEvalContext.fastStubOnly(file)); + final PyType type = TypeEvalContext.fastStubOnly(file).getType(problemElement); return (type == null || type instanceof PyReturnTypeReference); } diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java index c20cd4fc2e73..2b14c86a5bb2 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java @@ -68,7 +68,8 @@ public abstract class TypeIntention implements IntentionAction { protected abstract void updateText(boolean isReturn); private static boolean isTypeUndefined(PyExpression problemElement) { - final PyType type = problemElement.getType(TypeEvalContext.fastStubOnly(problemElement.getContainingFile())); + final TypeEvalContext context = TypeEvalContext.fastStubOnly(problemElement.getContainingFile()); + final PyType type = context.getType(problemElement); if (type == null || type instanceof PyReturnTypeReference || type instanceof PyDynamicallyEvaluatedType) { PsiReference reference = problemElement.getReference(); if (problemElement instanceof PyQualifiedExpression) { diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java index da7968059431..9802764908e4 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java @@ -156,12 +156,12 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { if ("contextlib.closing".equals(contextManager.getQualifiedName()) && withExpression instanceof PyCallExpression) { PyExpression closee = ((PyCallExpression)withExpression).getArgument(0, PyExpression.class); if (closee != null) { - return closee.getType(context); + return context.getType(closee); } } final String name = contextManager.getName(); if ("FileIO".equals(name) || "TextIOWrapper".equals(name) || "IOBase".equals(name) || "_IOBase".equals(name)) { - return withExpression.getType(context); + return context.getType(withExpression); } return null; } @@ -191,7 +191,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { if (p.isPositionalContainer() || p.isKeywordContainer() || name == null) { continue; } - final PyType argType = entry.getKey().getType(context); + final PyType argType = context.getType(entry.getKey()); final PyType paramType = getParameterTypeByQName(overloadedQName, name, anchor); if (PyTypeChecker.match(paramType, argType, context)) { if (paramType != null && !PyTypeChecker.isUnknown(argType)) { diff --git a/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java b/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java index c005ced7c2b8..722d8e8168cc 100644 --- a/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java +++ b/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java @@ -113,7 +113,7 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase body, PyReferenceExpression expression, @NotNull TypeEvalContext context) { - PyType type = expression.getType(context); + PyType type = context.getType(expression); describeTypeWithLinks(body, expression, type, context); } @@ -481,7 +481,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i @Nullable private static PyClass inferClassOfParameter(PsiElement context) { if (context instanceof PyNamedParameter) { - final PyType type = ((PyNamedParameter)context).getType(TypeEvalContext.fast()); + final PyType type = TypeEvalContext.fast().getType((PyNamedParameter)context); if (type instanceof PyClassType) { return ((PyClassType)type).getPyClass(); } diff --git a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java index 6314e6848bf3..8c3f64cd78c6 100644 --- a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java @@ -39,7 +39,7 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx { if (element instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); if (qualifier != null) { - final PyType type = qualifier.getType(TypeEvalContext.fast()); + final PyType type = TypeEvalContext.fast().getType(qualifier); if (type == null || type instanceof PyTypeReference) { final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); if (call != null && element == call.getCallee()) { diff --git a/python/src/com/jetbrains/python/inspections/PyAugmentAssignmentInspection.java b/python/src/com/jetbrains/python/inspections/PyAugmentAssignmentInspection.java index 323730bcbb25..6e139c1e1d80 100644 --- a/python/src/com/jetbrains/python/inspections/PyAugmentAssignmentInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyAugmentAssignmentInspection.java @@ -75,7 +75,7 @@ public class PyAugmentAssignmentInspection extends PyInspection { registerProblem(node, "Assignment can be replaced with augmented assignment", quickFix); } else { - final PyType type = rightExpression.getType(myTypeEvalContext); + final PyType type = myTypeEvalContext.getType(rightExpression); if (type != null) { final PyBuiltinCache cache = PyBuiltinCache.getInstance(rightExpression); if (PyTypeChecker.match(cache.getComplexType(), type, myTypeEvalContext) || diff --git a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java index 33d60b068516..42cf00554ddb 100644 --- a/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyBroadExceptionInspection.java @@ -38,7 +38,7 @@ public class PyBroadExceptionInspection extends PyInspection { } public static boolean equalsException(@NotNull PyClass cls, @NotNull TypeEvalContext context) { - final PyType type = cls.getType(context); + final PyType type = context.getType(cls); return "Exception".equals(cls.getName()) && type != null && type.isBuiltin(context); } @@ -56,7 +56,7 @@ public class PyBroadExceptionInspection extends PyInspection { registerProblem(node.getFirstChild(), "Too broad exception clause"); } if (exceptClass != null) { - final PyType type = exceptClass.getType(myTypeEvalContext); + final PyType type = myTypeEvalContext.getType(exceptClass); if (type instanceof PyClassType) { final PyClass cls = ((PyClassType)type).getPyClass(); final PyExpression target = node.getTarget(); diff --git a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java index 366b9d075cc9..dfaabb94bd98 100644 --- a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java @@ -58,7 +58,7 @@ public class PyCallingNonCallableInspection extends PyInspection { return; } if (!callable) { - final PyType calleeType = callee != null ? callee.getType(myTypeEvalContext) : type; + final PyType calleeType = callee != null ? myTypeEvalContext.getType(callee) : type; if (calleeType instanceof PyClassType) { registerProblem(node, String.format("'%s' object is not callable", calleeType.getName())); } @@ -77,6 +77,6 @@ public class PyCallingNonCallableInspection extends PyInspection { if (element instanceof PyQualifiedExpression && PyNames.CLASS.equals(element.getName())) { return true; } - return PyTypeChecker.isCallable(element.getType(context)); + return PyTypeChecker.isCallable(context.getType(element)); } } diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java index 4e751db39380..d46900231ca2 100644 --- a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java @@ -171,7 +171,7 @@ public class PyPropertyDefinitionInspection extends PyInspection { return; } if (resolved instanceof PyTypedElement) { - final PyType type = ((PyTypedElement)resolved).getType(myTypeEvalContext); + final PyType type = myTypeEvalContext.getType((PyTypedElement)resolved); final Boolean isCallable = PyTypeChecker.isCallable(type); if (isCallable != null && !isCallable) { registerProblem(element, PyBundle.message("INSP.strange.arg.want.callable")); diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java index 17638d594639..b7c46583b787 100644 --- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java @@ -182,7 +182,7 @@ public class PyStringFormatInspection extends PyInspection { } } else if (rightExpression instanceof PySliceExpression && s != null) { - final PyType type = ((PySliceExpression)rightExpression).getOperand().getType(myTypeEvalContext); + final PyType type = myTypeEvalContext.getType(((PySliceExpression)rightExpression).getOperand()); if (type == null || "list".equals(type.getName()) || "str".equals(type.getName())) { checkTypeCompatible(problemTarget, builtinCache.getStrType(), PyTypeParser.getTypeByName(problemTarget, s)); diff --git a/python/src/com/jetbrains/python/inspections/PySuperArgumentsInspection.java b/python/src/com/jetbrains/python/inspections/PySuperArgumentsInspection.java index 809ce6001739..f51a570e081b 100644 --- a/python/src/com/jetbrains/python/inspections/PySuperArgumentsInspection.java +++ b/python/src/com/jetbrains/python/inspections/PySuperArgumentsInspection.java @@ -70,7 +70,7 @@ public class PySuperArgumentsInspection extends PyInspection { PyClass firstClass = null; if (firstElement instanceof PyClass) firstClass = (PyClass)firstElement; else if (firstElement instanceof PyExpression) { - PyType first_type = ((PyExpression)firstElement).getType(myTypeEvalContext); + PyType first_type = myTypeEvalContext.getType((PyExpression)firstElement); if (first_type instanceof PyClassType) { firstClass = ((PyClassType)first_type).getPyClass(); } diff --git a/python/src/com/jetbrains/python/inspections/PyTupleAssignmentBalanceInspection.java b/python/src/com/jetbrains/python/inspections/PyTupleAssignmentBalanceInspection.java index 9ca11ac7b5c9..c024638cd615 100644 --- a/python/src/com/jetbrains/python/inspections/PyTupleAssignmentBalanceInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyTupleAssignmentBalanceInspection.java @@ -45,7 +45,7 @@ public class PyTupleAssignmentBalanceInspection extends PyInspection { lhsExpression = ((PyParenthesizedExpression)lhsExpression).getContainedExpression(); if (assignedValue == null) return; - PyType type = assignedValue.getType(myTypeEvalContext); + PyType type = myTypeEvalContext.getType(assignedValue); if (assignedValue instanceof PyReferenceExpression && !(type instanceof PyTupleType)) return; if (lhsExpression instanceof PyTupleExpression && type != null && !(type instanceof PyReturnTypeReference)){ int valuesLength = PyUtil.getElementsCount(assignedValue, myTypeEvalContext); diff --git a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java index 8be02c241f58..5b51beb6b42a 100644 --- a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java @@ -71,8 +71,8 @@ public class PyTypeCheckerInspection extends PyInspection { // TODO: Support *args, **kwargs continue; } - final PyType argType = entry.getKey().getType(myTypeEvalContext); - final PyType paramType = p.getType(myTypeEvalContext); + final PyType argType = myTypeEvalContext.getType(entry.getKey()); + final PyType paramType = myTypeEvalContext.getType(p); checkTypes(paramType, argType, entry.getKey(), myTypeEvalContext, substitutions); } } diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 434093821767..715e6de3e73b 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -574,7 +574,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { if (reference instanceof PyOperatorReference && element instanceof PyQualifiedExpression) { final PyExpression receiver = ((PyOperatorReference)reference).getReceiver(); if (receiver != null) { - final PyType type = receiver.getType(context); + final PyType type = context.getType(receiver); if (type instanceof PyClassType) { final String name = ((PyClassType)type).getClassQName(); if (name != null) { @@ -589,7 +589,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { final String exprName = expr.getName(); if (exprName != null) { if (qualifier != null) { - final PyType type = qualifier.getType(context); + final PyType type = context.getType(qualifier); if (type instanceof PyClassType) { final String name = ((PyClassType)type).getClassQName(); if (name != null) { @@ -810,7 +810,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { @Nullable private static PsiElement resolveClassMember(@NotNull PyClass cls, @NotNull String name) { final TypeEvalContext context = TypeEvalContext.fastStubOnly(null); - final PyType type = cls.getType(context); + final PyType type = context.getType(cls); if (type != null) { final List results = type.resolveMember(name, null, AccessDirection.READ, PyResolveContext.noImplicits().withTypeEvalContext(context)); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java index 5997138b0055..c855bd32c94a 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java @@ -69,7 +69,7 @@ public class AddMethodQuickFix implements LocalQuickFix { boolean made_instance = false; if (call_by_class) { if (args.length > 0) { - PyType first_arg_type = args[0].getType(TypeEvalContext.fast()); + PyType first_arg_type = TypeEvalContext.fast().getType(args[0]); if (first_arg_type instanceof PyClassType && ((PyClassType)first_arg_type).getPyClass().isSubclass(cls)) { // class, first arg ok: instance method builder.parameter("self"); // NOTE: might use a name other than 'self', according to code style. diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index c31172bfe239..4e26ba30eaa7 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1065,7 +1065,7 @@ public class PyUtil { */ public static int getElementsCount(PyExpression expression, TypeEvalContext evalContext) { int valuesLength = -1; - PyType type = expression.getType(evalContext); + PyType type = evalContext.getType(expression); if (type instanceof PyTupleType) { valuesLength = ((PyTupleType)type).getElementCount(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java index 1b5e21df8f3a..68cef9705ebf 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBinaryExpressionImpl.java @@ -108,7 +108,7 @@ public class PyBinaryExpressionImpl extends PyElementImpl implements PyBinaryExp return new PyOperatorReference(this, context); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCall(this, context); if (results != null) { final PyType type = results.getCallable().getReturnType(context, this); diff --git a/python/src/com/jetbrains/python/psi/impl/PyBoolLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyBoolLiteralExpressionImpl.java index af6dd0090f52..497611ac73d3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBoolLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBoolLiteralExpressionImpl.java @@ -15,7 +15,7 @@ public class PyBoolLiteralExpressionImpl extends PyElementImpl implements PyBool super(astNode); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyBuiltinCache.getInstance(this).getBoolType(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index aea70b28e570..f7b87c4ef41f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -360,12 +360,12 @@ public class PyCallExpressionHelper { final PyExpression[] args = call.getArguments(); if (args.length == 1) { final PyExpression arg = args[0]; - final PyType argType = arg.getType(context); + final PyType argType = context.getType(arg); if (argType instanceof PyClassType) { final PyClassType classType = (PyClassType)argType; if (!classType.isDefinition()) { final PyClass cls = classType.getPyClass(); - return cls.getType(context); + return context.getType(cls); } } else { diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java index b8d0fcb1cb0f..0fa29df39d2b 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java @@ -87,7 +87,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress return "PyCallExpression: " + PyUtil.getReadableRepr(getCallee(), true); //or: getCalledFunctionReference().getReferencedName(); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyCallExpressionHelper.getCallType(this, context); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 1c9e818fe85e..eabaa37e163a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -55,7 +55,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement private volatile Map myPropertyCache; @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return new PyClassTypeImpl(this, true); } @@ -276,7 +276,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement result.add(new PyClassRef(element)); } else { - final PyType type = expression.getType(context); + final PyType type = context.getType(expression); if (type instanceof PyClassType) { result.add(new PyClassRef((PyClassType)type)); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyConditionalExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyConditionalExpressionImpl.java index 061b3c5117cb..4fb67b3b1fca 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyConditionalExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyConditionalExpressionImpl.java @@ -20,7 +20,7 @@ public class PyConditionalExpressionImpl extends PyElementImpl implements PyCond super(astNode); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression truePart = getTruePart(); final PyExpression falsePart = getFalsePart(); if (truePart == null || falsePart == null) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java index b0c5d37004bd..05bee8401122 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java @@ -166,7 +166,7 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase im } } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyCallExpressionHelper.getCallType(this, context); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyDictCompExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDictCompExpressionImpl.java index 37b010313f4f..48bdd9d46e0f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyDictCompExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyDictCompExpressionImpl.java @@ -15,7 +15,7 @@ public class PyDictCompExpressionImpl extends PyComprehensionElementImpl impleme super(astNode); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyBuiltinCache.getInstance(this).getDictType(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyDictLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDictLiteralExpressionImpl.java index f5a507e6771f..7c66f1d195e6 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyDictLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyDictLiteralExpressionImpl.java @@ -22,7 +22,7 @@ public class PyDictLiteralExpressionImpl extends PyElementImpl implements PyDict return childrenToPsi(KEY_VALUE_EXPRESSIONS, PyKeyValueExpression.EMPTY_ARRAY); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyBuiltinCache.createLiteralCollectionType(this, "dict"); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyEmptyExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyEmptyExpressionImpl.java index da14e03f08d0..32fbdd6fd62d 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyEmptyExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyEmptyExpressionImpl.java @@ -14,7 +14,7 @@ public class PyEmptyExpressionImpl extends PyElementImpl implements PyEmptyExpre super(astNode); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return null; } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index 4e23b2c6e93d..5408cd0b9aee 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -704,7 +704,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { if (myType == null) myType = new PyModuleType(this); return myType; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index e15e43208c03..7edaf41d16da 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -193,7 +193,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp private static boolean isDynamicallyEvaluated(@NotNull Collection parameters, @NotNull TypeEvalContext context) { for (PyNamedParameter parameter : parameters) { - final PyType type = parameter.getType(context); + final PyType type = context.getType(parameter); if (type instanceof PyDynamicallyEvaluatedType) { return true; } @@ -245,7 +245,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp statements.accept(new PyRecursiveElementVisitor() { @Override public void visitPyYieldExpression(PyYieldExpression node) { - final PyType type = node.getType(context); + final PyType type = context.getType(node); if (node.isDelegating() && type instanceof PyCollectionType) { final PyCollectionType collectionType = (PyCollectionType)type; types.add(collectionType.getElementType(context)); @@ -330,7 +330,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp } @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyFunctionType type = new PyFunctionType(this); if (getDecoratorList() != null) { return PyUnionType.createWeakType(type); diff --git a/python/src/com/jetbrains/python/psi/impl/PyGeneratorExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyGeneratorExpressionImpl.java index 190a4eca6a13..8b8e91dc2db4 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyGeneratorExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyGeneratorExpressionImpl.java @@ -28,12 +28,12 @@ public class PyGeneratorExpressionImpl extends PyComprehensionElementImpl implem @Nullable @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression resultExpr = getResultExpression(); final PyBuiltinCache cache = PyBuiltinCache.getInstance(this); final PyClass generator = cache.getClass(PyNames.FAKE_GENERATOR); if (resultExpr != null && generator != null) { - final PyType elementType = resultExpr.getType(context); + final PyType elementType = context.getType(resultExpr); return new PyCollectionTypeImpl(generator, false, elementType); } return null; diff --git a/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java index 22fe2800c770..40acfb1959cf 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java @@ -18,12 +18,12 @@ public class PyKeyValueExpressionImpl extends PyElementImpl implements PyKeyValu super(astNode); } - public PyType getType(@NotNull TypeEvalContext context) { - final PyType keyType = getKey().getType(context); + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { + final PyType keyType = context.getType(getKey()); final PyExpression value = getValue(); PyType valueType = null; if (value != null) { - valueType = value.getType(context); + valueType = context.getType(value); } return PyTupleType.create(this, new PyType[] {keyType, valueType}); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java index 02cba3fe8e95..d43636eba7f4 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java @@ -42,9 +42,9 @@ public class PyKeywordArgumentImpl extends PyElementImpl implements PyKeywordArg return getClass().getSimpleName() + ": " + getKeyword(); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression e = getValueExpression(); - return e != null ? e.getType(context) : null; + return e != null ? context.getType(e) : null; } @Override diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java index 27380a9928fd..fc31ce2e21a3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java @@ -23,7 +23,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp pyVisitor.visitPyLambdaExpression(this); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return new PyFunctionType(this); } @@ -41,7 +41,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp @Override public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { final PyExpression body = getBody(); - if (body != null) return body.getType(context); + if (body != null) return context.getType(body); else return null; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyListCompExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyListCompExpressionImpl.java index 8e34c714795d..86ccc3e8dda7 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyListCompExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyListCompExpressionImpl.java @@ -26,12 +26,12 @@ public class PyListCompExpressionImpl extends PyComprehensionElementImpl impleme @Nullable @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression resultExpr = getResultExpression(); final PyBuiltinCache cache = PyBuiltinCache.getInstance(this); final PyClass list = cache.getClass("list"); if (resultExpr != null && list != null) { - final PyType elementType = resultExpr.getType(context); + final PyType elementType = context.getType(resultExpr); return new PyCollectionTypeImpl(list, false, elementType); } return cache.getListType(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyListLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyListLiteralExpressionImpl.java index c3b49b4938b1..3992aa4026ab 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyListLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyListLiteralExpressionImpl.java @@ -70,7 +70,7 @@ public class PyListLiteralExpressionImpl extends PyElementImpl implements PyList } } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { return PyBuiltinCache.createLiteralCollectionType(this, "list"); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java index 846b6fd27509..7f16c71e37a3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java @@ -153,7 +153,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl nodes = getStringNodes(); if (nodes.size() > 0) { String text = getStringNodes().get(0).getText(); diff --git a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java index 60656f93d531..2a85a5e1a891 100644 --- a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java @@ -38,7 +38,7 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub @Nullable @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { PyType res = null; final PsiReference ref = getReference(PyResolveContext.noImplicits().withTypeEvalContext(context)); if (ref != null) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index 9c3d3de54f1f..117983e93c69 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -98,7 +98,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl results = type.resolveMember(name, null, AccessDirection.READ, PyResolveContext.noImplicits()); diff --git a/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java index 98f9cea9df95..274a47584093 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java @@ -31,7 +31,7 @@ public class PyTupleExpressionImpl extends PyElementImpl implements PyTupleExpre return childrenToPsi(PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens(), PyExpression.EMPTY_ARRAY); } - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression[] elements = getElements(); final PyType[] types = new PyType[elements.length]; for (int i = 0; i < types.length; i++) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyYieldExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyYieldExpressionImpl.java index 3a8fa6b4d98a..8c294178d191 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyYieldExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyYieldExpressionImpl.java @@ -34,8 +34,8 @@ public class PyYieldExpressionImpl extends PyElementImpl implements PyYieldExpre } @Override - public PyType getType(@NotNull TypeEvalContext context) { + public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { final PyExpression e = getExpression(); - return e != null ? e.getType(context) : null; + return e != null ? context.getType(e) : null; } } diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java index 598960707eaa..cffc4a2790c2 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java @@ -83,7 +83,7 @@ public class PyImportReference extends PyReferenceImpl { PyExpression qualifier = myElement.getQualifier(); if (qualifier != null) { // qualifier's type must be module, it should know how to complete - PyType type = qualifier.getType(TypeEvalContext.fast()); + PyType type = TypeEvalContext.fast().getType(qualifier); if (type != null) { Object[] variants = getTypeCompletionVariants(myElement, type); if (!alreadyHasImportKeyword()) { @@ -177,7 +177,7 @@ public class PyImportReference extends PyReferenceImpl { addImportedNames(from_import.getImportElements()); // don't propose already imported items // try to collect submodules PyExpression module = (PyExpression)mod_candidate; - PyType qualifierType = module.getType(TypeEvalContext.fast()); + PyType qualifierType = TypeEvalContext.fast().getType(module); if (qualifierType != null) { ProcessingContext ctx = new ProcessingContext(); ctx.put(PyType.CTX_NAMES, myNamesAlready); diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java index 2fdd1a0539b2..d1453add6411 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java @@ -242,7 +242,7 @@ public class PyQualifiedReference extends PyReferenceImpl { assert qualifier != null; final PyQualifiedExpression element = CompletionUtil.getOriginalOrSelf(myElement); - PyType qualifierType = qualifier.getType(TypeEvalContext.slow()); + PyType qualifierType = TypeEvalContext.slow().getType(qualifier); ProcessingContext ctx = new ProcessingContext(); final Set namesAlready = new HashSet(); ctx.put(PyType.CTX_NAMES, namesAlready); @@ -382,7 +382,7 @@ public class PyQualifiedReference extends PyReferenceImpl { final PyExpression qualifier = myElement.getQualifier(); if (qualifier != null) { final TypeEvalContext context = TypeEvalContext.fast(); - PyType qualifierType = qualifier.getType(context); + PyType qualifierType = context.getType(qualifier); if (qualifierType == null || qualifierType instanceof PyTypeReference) { return true; } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 7dfd2861482f..631856cbee4b 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -136,7 +136,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { // methods of super() call are not of class super! PyExpression first_arg = ((PyCallExpression)location).getArgument(0, PyExpression.class); if (first_arg != null) { // the usual case: first arg is the derived class that super() is proxying for - PyType first_arg_type = first_arg.getType(resolveContext.getTypeEvalContext()); + PyType first_arg_type = resolveContext.getTypeEvalContext().getType(first_arg); if (first_arg_type instanceof PyClassType) { PyClass derived_class = ((PyClassType)first_arg_type).getPyClass(); final Iterator base_it = derived_class.iterateAncestorClasses().iterator(); @@ -212,7 +212,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { private PyClassType getMetaclassType() { final PyTargetExpression metaClassAttribute = myClass.findClassAttribute(PyNames.DUNDER_METACLASS, true); if (metaClassAttribute != null) { - final PyType type = metaClassAttribute.getType(TypeEvalContext.fastStubOnly(null)); + final PyType type = TypeEvalContext.fastStubOnly(null).getType(metaClassAttribute); if (type instanceof PyClassType) { return (PyClassType)type; } @@ -381,7 +381,8 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { type = new PyClassTypeImpl((PyClass)element, myIsDefinition); } else { - type = expression.getType(TypeEvalContext.fastStubOnly(myClass.getContainingFile())); + final TypeEvalContext typeEvalContext = TypeEvalContext.fastStubOnly(myClass.getContainingFile()); + type = typeEvalContext.getType(expression); if (type instanceof PyClassType && !myIsDefinition) { type = ((PyClassType)type).toInstance(); } diff --git a/python/src/com/jetbrains/python/psi/types/PyLiteralCollectionType.java b/python/src/com/jetbrains/python/psi/types/PyLiteralCollectionType.java index cab7a96a6fd7..159deb29958d 100644 --- a/python/src/com/jetbrains/python/psi/types/PyLiteralCollectionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyLiteralCollectionType.java @@ -27,7 +27,7 @@ public class PyLiteralCollectionType extends PyClassTypeImpl implements PyCollec return null; } for (int i = 1; i < elements.length; i++) { - PyType elementType = elements [i].getType(context); + PyType elementType = context.getType(elements[i]); if (elementType == null || !elementType.equals(result)) { return null; } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 8157c052f6dc..d998ec79dbab 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -261,8 +261,8 @@ public class PyTypeChecker { final Map substitutions = collectCallGenerics(function, receiver, context); for (Map.Entry entry : arguments.entrySet()) { final PyNamedParameter p = entry.getValue(); - final PyType argType = entry.getKey().getType(context); - final PyType paramType = p.getType(context); + final PyType argType = context.getType(entry.getKey()); + final PyType paramType = context.getType(p); if (!match(paramType, argType, context, substitutions)) { return null; } @@ -276,7 +276,7 @@ public class PyTypeChecker { final Map substitutions = new LinkedHashMap(); // Collect generic params of object type final Set generics = new LinkedHashSet(); - final PyType qualifierType = receiver != null ? receiver.getType(context) : null; + final PyType qualifierType = receiver != null ? context.getType(receiver) : null; collectGenerics(qualifierType, context, generics, new HashSet()); for (PyGenericType t : generics) { substitutions.put(t, t); @@ -388,7 +388,7 @@ public class PyTypeChecker { final PsiReference ref = expr.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context)); final PsiElement resolved = ref.resolve(); if (resolved instanceof PyTypedElement) { - final PyType type = ((PyTypedElement)resolved).getType(context); + final PyType type = context.getType((PyTypedElement)resolved); if (type instanceof PyFunctionType) { final Callable callable = ((PyFunctionType)type).getCallable(); final PyParameter[] parameters = callable.getParameterList().getParameters(); @@ -479,7 +479,7 @@ public class PyTypeChecker { public static boolean isResolvedToSeveralMethods(@NotNull PyQualifiedExpression callee, @NotNull TypeEvalContext context) { final PyExpression qualifier = callee.getQualifier(); if (qualifier != null) { - final PyType qualifierType = qualifier.getType(context); + final PyType qualifierType = context.getType(qualifier); if (qualifierType instanceof PyUnionType) { final PyUnionType unionType = (PyUnionType)qualifierType; final String name = callee.getName(); diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index f2ec421d91ee..f7e20b6c94d2 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -246,7 +246,7 @@ public class PyTypeParser { final RatedResolveResult result = results.get(0); final PsiElement resolved = result.getElement(); if (resolved instanceof PyTypedElement) { - PyType t = ((PyTypedElement)resolved).getType(context.getTypeEvalContext()); + PyType t = context.getTypeEvalContext().getType((PyTypedElement)resolved); if (t instanceof PyClassType) { t = ((PyClassType)t).toInstance(); } diff --git a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java index fa06d2093ea9..abd91f32fc58 100644 --- a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java +++ b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java @@ -111,7 +111,7 @@ public class PyReplaceExpressionUtil implements PyElementTypes { } else { final TypeEvalContext context = TypeEvalContext.slow(); - final PyType valueType = formatValue.getType(context); + final PyType valueType = context.getType(formatValue); final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(oldExpression); final PyType tupleType = builtinCache.getTupleType(); final PyType mappingType = PyTypeParser.getTypeByName(null, "collections.Mapping"); diff --git a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java index 8f970440f578..6f6bed984a18 100644 --- a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java +++ b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java @@ -189,7 +189,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler { candidates.addAll(NameSuggesterUtil.generateNames(text)); } final TypeEvalContext context = TypeEvalContext.slow(); - PyType type = expression.getType(context); + PyType type = context.getType(expression); if (type != null && type != PyNoneType.INSTANCE) { String typeName = type.getName(); if (typeName != null) { diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 87a250a2ddf1..d023461516fe 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -220,7 +220,7 @@ public class PyTypeTest extends PyTestCase { " return x\n" + "expr = f(1, 2)\n"; PyExpression expr = parseExpr(text); - PyType t = expr.getType(TypeEvalContext.slow()); + PyType t = TypeEvalContext.slow().getType(expr); assertTrue(PyTypeChecker.isUnknown(t)); doTest("int", text); } @@ -234,7 +234,7 @@ public class PyTypeTest extends PyTestCase { " return foo(x)\n" + "expr = xyzzy(a, b)"; PyExpression expr = parseExpr(text); - PyType t = expr.getType(TypeEvalContext.slow()); + PyType t = TypeEvalContext.slow().getType(expr); assertInstanceOf(t, PyTypeReference.class); } @@ -297,7 +297,7 @@ public class PyTypeTest extends PyTestCase { PyExpression expr = parseExpr("def foo(x): return foo(x)\n" + "expr = foo(1)"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); assertFalse(actual.isBuiltin(context)); } @@ -311,7 +311,7 @@ public class PyTypeTest extends PyTestCase { "\n" + "expr = f(1)\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); assertNotNull(actual); assertEquals("int", actual.getName()); } @@ -326,7 +326,7 @@ public class PyTypeTest extends PyTestCase { "\n" + "expr = f(1)\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); assertNotNull(actual); assertEquals("int", actual.getName()); } @@ -336,7 +336,7 @@ public class PyTypeTest extends PyTestCase { PyExpression expr = parseExpr("def f():\n" + " expr = yield 2\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); assertNull(actual); } @@ -381,7 +381,7 @@ public class PyTypeTest extends PyTestCase { "x = f()\n" + "expr = x.start\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); assertNull(actual); } @@ -393,7 +393,7 @@ public class PyTypeTest extends PyTestCase { "x = C()\n" + "expr = type(x)\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType type = expr.getType(context); + PyType type = context.getType(expr); assertInstanceOf(type, PyClassType.class); assertTrue("Got instance type instead of class type", ((PyClassType)type).isDefinition()); } @@ -405,7 +405,7 @@ public class PyTypeTest extends PyTestCase { "\n" + "expr = type(C)\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType type = expr.getType(context); + PyType type = context.getType(expr); assertInstanceOf(type, PyClassType.class); assertEquals(type.getName(), "type"); } @@ -415,7 +415,7 @@ public class PyTypeTest extends PyTestCase { PyExpression expr = parseExpr("def f(x):\n" + " expr = type(x)\n"); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType type = expr.getType(context); + PyType type = context.getType(expr); assertNull(type); } @@ -445,7 +445,7 @@ public class PyTypeTest extends PyTestCase { public void testListComprehensionType() { final PyExpression expr = parseExpr("expr = [str(x) for x in range(10)]\n"); final TypeEvalContext context = TypeEvalContext.slow().withTracing(); - final PyType type = expr.getType(context); + final PyType type = context.getType(expr); assertNotNull(type); assertInstanceOf(type, PyCollectionType.class); assertEquals(type.getName(), "list"); @@ -459,7 +459,7 @@ public class PyTypeTest extends PyTestCase { public void testGeneratorComprehensionType() { final PyExpression expr = parseExpr("expr = (str(x) for x in range(10))\n"); final TypeEvalContext context = TypeEvalContext.slow().withTracing(); - final PyType type = expr.getType(context); + final PyType type = context.getType(expr); assertNotNull(type); assertInstanceOf(type, PyCollectionType.class); assertEquals(type.getName(), "__generator"); @@ -491,7 +491,7 @@ public class PyTypeTest extends PyTestCase { private void doTest(final String expectedType, final String text) { PyExpression expr = parseExpr(text); TypeEvalContext context = TypeEvalContext.slow().withTracing(); - PyType actual = expr.getType(context); + PyType actual = context.getType(expr); PyType expected = PyTypeParser.getTypeByName(expr, expectedType); if (expected != null) { assertNotNull(context.printTrace(), actual); From 20fea10c333551b8390c1b557331fcf8f4f15ea0 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 5 Feb 2013 19:50:35 +0100 Subject: [PATCH 04/54] Fixed python console for remote interpreters (PY-8734). --- python/helpers/pydev/pydev_ipython_console.py | 8 +++----- python/helpers/pydev/pydev_ipython_console_010.py | 3 +++ python/helpers/pydev/pydev_ipython_console_011.py | 3 +++ python/helpers/pydev/pydevconsole.py | 8 ++++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/python/helpers/pydev/pydev_ipython_console.py b/python/helpers/pydev/pydev_ipython_console.py index 79f049129cf8..2175c02d2cca 100644 --- a/python/helpers/pydev/pydev_ipython_console.py +++ b/python/helpers/pydev/pydev_ipython_console.py @@ -12,15 +12,10 @@ os.environ['TERM'] = 'emacs' #to use proper page_more() for paging try: from pydev_ipython_console_010 import PyDevFrontEnd - - sys.stderr.write('PyDev console: using IPython 0.10\n') except: #IPython 0.11 broke compatibility... from pydev_ipython_console_011 import PyDevFrontEnd - sys.stderr.write('PyDev console: using IPython %s\n' % PyDevFrontEnd.version) - - #======================================================================================================================= # InterpreterInterface #======================================================================================================================= @@ -41,6 +36,9 @@ class InterpreterInterface(BaseInterpreterInterface): self.notify_about_magic() + def get_greeting_msg(self): + return self.interpreter.get_greeting_msg() + def doAddExec(self, line): self.notify_about_magic() if (line.rstrip().endswith('??')): diff --git a/python/helpers/pydev/pydev_ipython_console_010.py b/python/helpers/pydev/pydev_ipython_console_010.py index c3473fb7ad56..e093fefe9a32 100644 --- a/python/helpers/pydev/pydev_ipython_console_010.py +++ b/python/helpers/pydev/pydev_ipython_console_010.py @@ -124,3 +124,6 @@ class PyDevFrontEnd(PrefilterFrontEnd): else: return False + def get_greeting_msg(self): + return 'PyDev console: using IPython 0.10\n' + diff --git a/python/helpers/pydev/pydev_ipython_console_011.py b/python/helpers/pydev/pydev_ipython_console_011.py index 34227ce32f5d..34cd2371a3a5 100644 --- a/python/helpers/pydev/pydev_ipython_console_011.py +++ b/python/helpers/pydev/pydev_ipython_console_011.py @@ -144,3 +144,6 @@ class PyDevFrontEnd: def is_automagic(self): return self.ipython.automagic + def get_greeting_msg(self): + sys.stderr.write('PyDev console: using IPython %s\n' % self.version) + diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py index fd2086b08d88..6789497bd87b 100644 --- a/python/helpers/pydev/pydevconsole.py +++ b/python/helpers/pydev/pydevconsole.py @@ -165,6 +165,9 @@ class InterpreterInterface(BaseInterpreterInterface): def close(self): sys.exit(0) + def get_greeting_msg(self): + return 'PyDev console: starting.\n' + def process_exec_queue(interpreter): while 1: @@ -277,6 +280,9 @@ def start_server(host, port, interpreter): print(port) print(client_port) + + sys.stderr.write(interpreter.get_greeting_msg()) + server.serve_forever() return server @@ -295,8 +301,6 @@ def StartServer(host, port, client_port): server_thread.setDaemon(True) server_thread.start() - if not IPYTHON: - sys.stderr.write('PyDev console: starting.\n') process_exec_queue(interpreter) From 07670e087f4d7c4533c9697b13b8229309e07cc2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 13:58:02 +0100 Subject: [PATCH 05/54] read action when collecting package usages (PY-8723) --- .../statistics/PyPackageUsagesCollector.java | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java b/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java index e388a44b8333..b2e70a75b6a7 100644 --- a/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java +++ b/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java @@ -4,6 +4,7 @@ import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.internal.statistic.CollectUsagesException; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -26,26 +27,31 @@ public class PyPackageUsagesCollector extends AbstractApplicationUsagesCollector @NotNull @Override public Set getProjectUsages(@NotNull Project project) throws CollectUsagesException { - Set result = new HashSet(); - for(Module m: ModuleManager.getInstance(project).getModules()) { + final Set result = new HashSet(); + for(final Module m: ModuleManager.getInstance(project).getModules()) { Sdk pythonSdk = PythonSdkType.findPythonSdk(m); if (pythonSdk != null) { - List requirements = PyPackageManagerImpl.getRequirements(m); - if (requirements != null) { - Collection packages; - try { - packages = new HashSet(PyPIPackageUtil.INSTANCE.getPackageNames()); - } - catch (IOException e) { - continue; - } - for (PyRequirement requirement : requirements) { - String name = requirement.getName(); - if (packages.contains(name)) { - result.add(new UsageDescriptor(name, 1)); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + List requirements = PyPackageManagerImpl.getRequirements(m); + if (requirements != null) { + Collection packages; + try { + packages = new HashSet(PyPIPackageUtil.INSTANCE.getPackageNames()); + } + catch (IOException e) { + return; + } + for (PyRequirement requirement : requirements) { + String name = requirement.getName(); + if (packages.contains(name)) { + result.add(new UsageDescriptor(name, 1)); + } + } } } - } + }); } } return result; From b6326c60903315e4dc45e4c1f49be0072d7031ca Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 16:54:00 +0100 Subject: [PATCH 06/54] EA-43567 - assert: UsageDescriptor. --- .../python/statistics/PyInterpreterUsagesCollector.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/statistics/PyInterpreterUsagesCollector.java b/python/src/com/jetbrains/python/statistics/PyInterpreterUsagesCollector.java index b66718b7b264..a1c5830a932b 100644 --- a/python/src/com/jetbrains/python/statistics/PyInterpreterUsagesCollector.java +++ b/python/src/com/jetbrains/python/statistics/PyInterpreterUsagesCollector.java @@ -27,7 +27,10 @@ public class PyInterpreterUsagesCollector extends AbstractApplicationUsagesColle for(Module m: ModuleManager.getInstance(project).getModules()) { Sdk pythonSdk = PythonSdkType.findPythonSdk(m); if (pythonSdk != null) { - result.add(new UsageDescriptor(pythonSdk.getVersionString(), 1)); + String versionString = pythonSdk.getVersionString(); + if (versionString != null) { + result.add(new UsageDescriptor(versionString, 1)); + } } } return result; From e0b317d2f9b50ae904c085b5f42e24f9d11a4409 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 16:55:56 +0100 Subject: [PATCH 07/54] ReformatFix prompts to make file writable (EA-43561 - IOE: CheckUtil.checkWritable) --- .../jetbrains/python/inspections/quickfix/ReformatFix.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/src/com/jetbrains/python/inspections/quickfix/ReformatFix.java b/python/src/com/jetbrains/python/inspections/quickfix/ReformatFix.java index 5f9879999f1a..560e4578256e 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/ReformatFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/ReformatFix.java @@ -1,5 +1,6 @@ package com.jetbrains.python.inspections.quickfix; +import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.LocalQuickFix; @@ -45,6 +46,9 @@ public class ReformatFix implements IntentionAction, LocalQuickFix, HighPriority @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (!CodeInsightUtilBase.prepareFileForWrite(file)) { + return; + } CodeStyleManager.getInstance(project).reformat(file); } From adeed1bdc19eb764b7bda619c9277f4b65fd49e9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 18:26:27 +0100 Subject: [PATCH 08/54] 2013 copyright year --- python/build/resources/logo.bmp | Bin 154542 -> 206038 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/python/build/resources/logo.bmp b/python/build/resources/logo.bmp index 5ff00b6ed249d6a4294f6a559540d3415cf67cc8..7959278c30c93c3600cd27c4c0ba7ed7b2e0798a 100644 GIT binary patch literal 206038 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 literal 154542 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 From 764c6b4a975d2b797db4e316439a327cb2ab2804 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 18:56:29 +0100 Subject: [PATCH 09/54] log failures to run pep8.py --- .../jetbrains/python/validation/Pep8ExternalAnnotator.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python/src/com/jetbrains/python/validation/Pep8ExternalAnnotator.java b/python/src/com/jetbrains/python/validation/Pep8ExternalAnnotator.java index ec07ef4f134c..98fd2eb652e3 100644 --- a/python/src/com/jetbrains/python/validation/Pep8ExternalAnnotator.java +++ b/python/src/com/jetbrains/python/validation/Pep8ExternalAnnotator.java @@ -11,6 +11,9 @@ import com.intellij.execution.process.ProcessOutput; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.ExternalAnnotator; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.impl.ApplicationInfoImpl; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.module.ModuleUtilCore; @@ -47,6 +50,7 @@ import java.util.regex.Pattern; * @author yole */ public class Pep8ExternalAnnotator extends ExternalAnnotator { + private static final Logger LOG = Logger.getInstance(Pep8ExternalAnnotator.class); public static class Problem { private final int myLine; @@ -128,6 +132,9 @@ public class Pep8ExternalAnnotator extends ExternalAnnotator Date: Tue, 5 Feb 2013 19:36:22 +0100 Subject: [PATCH 10/54] don't cache file template in 'create setup.py' action (PY-6681) --- .../python/packaging/setupPy/CreateSetupPyAction.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python/src/com/jetbrains/python/packaging/setupPy/CreateSetupPyAction.java b/python/src/com/jetbrains/python/packaging/setupPy/CreateSetupPyAction.java index 2a969d67d5f7..9fcd9c49c149 100644 --- a/python/src/com/jetbrains/python/packaging/setupPy/CreateSetupPyAction.java +++ b/python/src/com/jetbrains/python/packaging/setupPy/CreateSetupPyAction.java @@ -1,6 +1,7 @@ package com.jetbrains.python.packaging.setupPy; import com.intellij.ide.IdeView; +import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.fileTemplates.actions.AttributesDefaults; import com.intellij.ide.fileTemplates.actions.CreateFromTemplateAction; @@ -40,6 +41,12 @@ public class CreateSetupPyAction extends CreateFromTemplateAction { getTemplatePresentation().setText("Create setup.py"); } + @Override + public FileTemplate getTemplate() { + // to ensure changes are picked up, reload the template on every call (PY-6681) + return FileTemplateManager.getInstance().getInternalTemplate("Setup Script"); + } + @Override public void update(AnActionEvent e) { final Module module = e.getData(LangDataKeys.MODULE); From 108b42b84bc85bc630944ad7b5279b30bc6e39d2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 19:52:23 +0100 Subject: [PATCH 11/54] when completing members of imported module, look at local imports, not only file-level ones (PY-3668) --- .../jetbrains/python/psi/types/PyImportedModuleType.java | 6 +++++- .../src/com/jetbrains/python/psi/types/PyModuleType.java | 2 +- python/testData/completion/py3668/foo/__init__.py | 0 python/testData/completion/py3668/foo/bar.py | 0 python/testData/completion/py3668/py3668.after.py | 3 +++ python/testData/completion/py3668/py3668.py | 3 +++ .../testSrc/com/jetbrains/python/PythonCompletionTest.java | 7 +++++++ 7 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 python/testData/completion/py3668/foo/__init__.py create mode 100644 python/testData/completion/py3668/foo/bar.py create mode 100644 python/testData/completion/py3668/py3668.after.py create mode 100644 python/testData/completion/py3668/py3668.py diff --git a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java index 9a06a4f61263..29b50a8f7c71 100644 --- a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java @@ -4,7 +4,9 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; +import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyFile; @@ -51,7 +53,9 @@ public class PyImportedModuleType implements PyType { public Object[] getCompletionVariants(String completionPrefix, PyExpression location, ProcessingContext context) { List result = new ArrayList(); - final List importTargets = myImportedModule.getContainingFile().getImportTargets(); + ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(location, ScopeOwner.class); + assert scopeOwner != null; + final List importTargets = PyModuleType.getVisibleImports(scopeOwner); final int imported = myImportedModule.getImportedPrefix().getComponentCount(); for (PyImportElement importTarget : importTargets) { final PyQualifiedName qName = importTarget.getImportedQName(); diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java index e4e1754fdce5..70d0d9f23219 100644 --- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java @@ -167,7 +167,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje } @NotNull - private static List getVisibleImports(@NotNull ScopeOwner owner) { + public static List getVisibleImports(@NotNull ScopeOwner owner) { final List visibleImports = new ArrayList(); PyResolveUtil.scopeCrawlUp(new PsiScopeProcessor() { @Override diff --git a/python/testData/completion/py3668/foo/__init__.py b/python/testData/completion/py3668/foo/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/py3668/foo/bar.py b/python/testData/completion/py3668/foo/bar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/py3668/py3668.after.py b/python/testData/completion/py3668/py3668.after.py new file mode 100644 index 000000000000..352310d2ca45 --- /dev/null +++ b/python/testData/completion/py3668/py3668.after.py @@ -0,0 +1,3 @@ +def func(): + import foo.bar + foo.bar diff --git a/python/testData/completion/py3668/py3668.py b/python/testData/completion/py3668/py3668.py new file mode 100644 index 000000000000..f3f5379fc8c9 --- /dev/null +++ b/python/testData/completion/py3668/py3668.py @@ -0,0 +1,3 @@ +def func(): + import foo.bar + foo. diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index 044c6208fc44..2cf060e79998 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -613,4 +613,11 @@ public class PythonCompletionTest extends PyTestCase { doTestByText("def foo(**)"); myFixture.checkResult("def foo(**kwargs)"); } + + public void testLocalImportedModule() { // PY-3668 + myFixture.copyDirectoryToProject("completion/py3668", ""); + myFixture.configureByFile("py3668.py"); + myFixture.completeBasic(); + myFixture.checkResultByFile("completion/py3668/py3668.after.py"); + } } From f4d2b40874310d71850c98d416f09fe08bb28538 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 20:06:50 +0100 Subject: [PATCH 12/54] find usages considers a reference to be a usage if it resolves to an element that shadows our name or is shadowed by ours (PY-6241) --- .../psi/impl/references/PyReferenceImpl.java | 6 ++++++ python/testData/findUsages/NameShadowing.py | 16 ++++++++++++++++ .../com/jetbrains/python/PyFindUsagesTest.java | 5 +++++ 3 files changed, 27 insertions(+) create mode 100644 python/testData/findUsages/NameShadowing.py diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index 30088c1af90a..2f272076c709 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -446,6 +446,12 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference return true; } + // we shadow their name or they shadow ours (PY-6241) + if (resolveResult instanceof PsiNamedElement && resolveResult instanceof ScopeOwner && element instanceof ScopeOwner && + ourScopeOwner == PsiTreeUtil.getParentOfType(resolveResult, ScopeOwner.class)) { + return true; + } + if (!haveQualifiers(element) && ourScopeOwner != null && theirScopeOwner != null) { if (resolvesToSameGlobal(element, elementName, ourScopeOwner, theirScopeOwner, resolveResult)) return true; } diff --git a/python/testData/findUsages/NameShadowing.py b/python/testData/findUsages/NameShadowing.py new file mode 100644 index 000000000000..fa06cb85b844 --- /dev/null +++ b/python/testData/findUsages/NameShadowing.py @@ -0,0 +1,16 @@ +class C(object): + def __init__(self): + self._x = None + + @property + def x(self): + """I'm the 'x' property.""" + return self._x + + @x.setter + def x(self, value): + self._x = value + + @x.deleter + def x(self): + del self._x \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java b/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java index 956b7867b150..436b3860bd6d 100644 --- a/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java +++ b/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java @@ -127,6 +127,11 @@ public class PyFindUsagesTest extends PyTestCase { } } + public void testNameShadowing() { // PY-6241 + final Collection usages = myFixture.testFindUsages("findUsages/NameShadowing.py"); + assertEquals(2, usages.size()); + } + private Collection findMultiFileUsages(String filename) { final String testName = getTestName(false); myFixture.copyDirectoryToProject("findUsages/" + testName, ""); From cc5af2c1e804013d5964593eefed8f2214c30c8e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 20:35:14 +0100 Subject: [PATCH 13/54] don't show duplicate names in completion list inside __all__ (PY-6483) --- .../python/codeInsight/PyDunderAllReference.java | 12 ++++++++++-- .../com/jetbrains/python/PythonCompletionTest.java | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java index fc0b93b47984..eef673349ac0 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java +++ b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java @@ -19,7 +19,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * @author yole @@ -47,18 +49,24 @@ public class PyDunderAllReference extends PsiReferenceBase result = new ArrayList(); PyFile containingFile = (PyFile) getElement().getContainingFile().getOriginalFile(); final List dunderAll = containingFile.getDunderAll(); + final Set seenNames = new HashSet(); + if (dunderAll != null) { + seenNames.addAll(dunderAll); + } containingFile.processDeclarations(new PsiScopeProcessor() { @Override public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiNamedElement && !(element instanceof LightNamedElement)) { final String name = ((PsiNamedElement)element).getName(); - if (name != null && PyUtil.getInitialUnderscores(name) == 0 && (dunderAll == null || !dunderAll.contains(name))) { + if (name != null && PyUtil.getInitialUnderscores(name) == 0 && !seenNames.contains(name)) { + seenNames.add(name); result.add(LookupElementBuilder.create((PsiNamedElement) element).withIcon(element.getIcon(0))); } } else if (element instanceof PyImportElement) { final String visibleName = ((PyImportElement)element).getVisibleName(); - if (visibleName != null && (dunderAll == null || !dunderAll.contains(visibleName))) { + if (visibleName != null && !seenNames.contains(visibleName)) { + seenNames.add(visibleName); result.add(LookupElementBuilder.create(element, visibleName)); } } diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index 2cf060e79998..c08b75db28d6 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -620,4 +620,11 @@ public class PythonCompletionTest extends PyTestCase { myFixture.completeBasic(); myFixture.checkResultByFile("completion/py3668/py3668.after.py"); } + + public void testDuplicateDunderAll() { // PY-6483 + doTestByText("VAR = 1\nVAR = 2\n__all__ = ['']"); + myFixture.checkResult("VAR = 1\n" + + "VAR = 2\n" + + "__all__ = ['VAR']"); + } } From be342bc7ffb15577a87e71a2a4f9cc8cbe6e74f6 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 20:36:59 +0100 Subject: [PATCH 14/54] correctly look for scope owner when checking name shadowing --- .../jetbrains/python/psi/impl/references/PyReferenceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index 2f272076c709..a68d688047f5 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -448,7 +448,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference // we shadow their name or they shadow ours (PY-6241) if (resolveResult instanceof PsiNamedElement && resolveResult instanceof ScopeOwner && element instanceof ScopeOwner && - ourScopeOwner == PsiTreeUtil.getParentOfType(resolveResult, ScopeOwner.class)) { + ourScopeOwner == ScopeUtil.getScopeOwner(resolveResult)) { return true; } From 2be20a61e046990a74a207673a9f85d601ad0cd6 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 20:46:35 +0100 Subject: [PATCH 15/54] 'with' statement also requires continuation indent for its condition (PY-8743) --- python/src/com/jetbrains/python/formatter/PyBlock.java | 3 ++- python/testData/formatter/longWith.py | 3 +++ python/testData/formatter/longWith_after.py | 3 +++ .../testSrc/com/jetbrains/python/PyFormatterTest.java | 10 ++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 python/testData/formatter/longWith.py create mode 100644 python/testData/formatter/longWith_after.py diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java index 9a79e0a00565..5f9cd0d0f834 100644 --- a/python/src/com/jetbrains/python/formatter/PyBlock.java +++ b/python/src/com/jetbrains/python/formatter/PyBlock.java @@ -242,7 +242,8 @@ public class PyBlock implements ASTBlock { } private boolean isInControlStatement() { - return PsiTreeUtil.getParentOfType(_node.getPsi(), PyStatementPart.class, false, PyStatementList.class) != null; + return PsiTreeUtil.getParentOfType(_node.getPsi(), PyStatementPart.class, false, PyStatementList.class) != null || + PsiTreeUtil.getParentOfType(_node.getPsi(), PyWithItem.class) != null; } private boolean isSliceOperand(ASTNode child) { diff --git a/python/testData/formatter/longWith.py b/python/testData/formatter/longWith.py new file mode 100644 index 000000000000..a34fd4294994 --- /dev/null +++ b/python/testData/formatter/longWith.py @@ -0,0 +1,3 @@ +with really_long_name_of_the_function_with_a_lot_of_params( + param1, param2, param3) as item: + pass \ No newline at end of file diff --git a/python/testData/formatter/longWith_after.py b/python/testData/formatter/longWith_after.py new file mode 100644 index 000000000000..c6aacb7cde67 --- /dev/null +++ b/python/testData/formatter/longWith_after.py @@ -0,0 +1,3 @@ +with really_long_name_of_the_function_with_a_lot_of_params( + param1, param2, param3) as item: + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java index 83e638c664f9..f17d0a2ecd63 100644 --- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java +++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java @@ -290,6 +290,16 @@ public class PyFormatterTest extends PyTestCase { doTest(); } + public void testLongWith() { // PY-8743 + PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON27); + try { + doTest(); + } + finally { + PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null); + } + } + private void doTest() { myFixture.configureByFile("formatter/" + getTestName(true) + ".py"); ApplicationManager.getApplication().runWriteAction(new Runnable() { From baed9c4be62672297e39dbba917657cc74170d52 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 20:48:52 +0100 Subject: [PATCH 16/54] look at correct scope owner --- .../jetbrains/python/psi/impl/references/PyReferenceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index a68d688047f5..2cb1e79ce8b7 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -448,7 +448,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference // we shadow their name or they shadow ours (PY-6241) if (resolveResult instanceof PsiNamedElement && resolveResult instanceof ScopeOwner && element instanceof ScopeOwner && - ourScopeOwner == ScopeUtil.getScopeOwner(resolveResult)) { + theirScopeOwner == ScopeUtil.getScopeOwner(resolveResult)) { return true; } From 4c7a2fd177b605830f859a08e2c36b14729aafbb Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 21:09:21 +0100 Subject: [PATCH 17/54] second half of fix for PY-7887 --- .../codeInsight/imports/AddImportHelper.java | 15 ++++++----- .../src/com/jetbrains/python/psi/PyUtil.java | 6 +++++ .../python/psi/resolve/VariantsProcessor.java | 4 +-- .../submoduleRegularImport/pack/__init__.py | 0 .../submoduleRegularImport/pack/submod.py | 0 .../submoduleRegularImport.after.py | 3 +++ .../submoduleRegularImport.py | 1 + .../python/PyClassNameCompletionTest.java | 26 ++++++++++++------- 8 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 python/testData/completion/className/submoduleRegularImport/pack/__init__.py create mode 100644 python/testData/completion/className/submoduleRegularImport/pack/submod.py create mode 100644 python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.after.py create mode 100644 python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.py diff --git a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java index 375406fd68ed..3469eb7cd56e 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/AddImportHelper.java @@ -226,14 +226,17 @@ public class AddImportHelper { if (target instanceof PsiFileSystemItem && qName.getComponentCount() == 1) { addImportStatement(file, path, null, priority); } - else if (useQualified) { - addImportStatement(file, path, null, priority); - final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(file.getProject()); - element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(target), qName + "." + target.getName())); - } else { final PyQualifiedName toImportQName = QualifiedNameFinder.findCanonicalImportPath(toImport, element); - addImportFrom(file, null, toImportQName.toString(), target.getName(), null, priority); + if (useQualified) { + addImportStatement(file, path, null, priority); + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(file.getProject()); + final String targetName = PyUtil.getElementNameWithoutExtension(target); + element.replace(elementGenerator.createExpressionFromText(LanguageLevel.forElement(target), toImportQName + "." + targetName)); + } + else { + addImportFrom(file, null, toImportQName.toString(), target.getName(), null, priority); + } } } diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 4e26ba30eaa7..12a2870fe860 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -609,6 +609,12 @@ public class PyUtil { } } + public static String getElementNameWithoutExtension(PsiNamedElement psiNamedElement) { + return psiNamedElement instanceof PyFile + ? FileUtil.getNameWithoutExtension(((PyFile)psiNamedElement).getName()) + : psiNamedElement.getName(); + } + public static boolean hasUnresolvedAncestors(@NotNull PyClass cls) { for (PyClassRef classRef : cls.iterateAncestors()) { if (classRef.getPyClass() == null && classRef.getType() == null) { diff --git a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java index 96e067dff963..f79cb9014052 100644 --- a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java +++ b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java @@ -50,9 +50,7 @@ public abstract class VariantsProcessor implements PsiScopeProcessor { // TODO: refactor to look saner; much code duplication if (element instanceof PsiNamedElement) { final PsiNamedElement psiNamedElement = (PsiNamedElement)element; - final String name = psiNamedElement instanceof PyFile - ? FileUtil.getNameWithoutExtension(((PyFile)psiNamedElement).getName()) - : psiNamedElement.getName(); + final String name = PyUtil.getElementNameWithoutExtension(psiNamedElement); if (name != null && nameIsAcceptable(name)) { addElement(name, psiNamedElement); } diff --git a/python/testData/completion/className/submoduleRegularImport/pack/__init__.py b/python/testData/completion/className/submoduleRegularImport/pack/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/className/submoduleRegularImport/pack/submod.py b/python/testData/completion/className/submoduleRegularImport/pack/submod.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.after.py b/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.after.py new file mode 100644 index 000000000000..f75256736d24 --- /dev/null +++ b/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.after.py @@ -0,0 +1,3 @@ +import pack.submod + +pack.submod diff --git a/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.py b/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.py new file mode 100644 index 000000000000..69cc258a0332 --- /dev/null +++ b/python/testData/completion/className/submoduleRegularImport/submoduleRegularImport.py @@ -0,0 +1 @@ +subm diff --git a/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java b/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java index 11d8d770e356..c4fea2e2093a 100644 --- a/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PyClassNameCompletionTest.java @@ -18,15 +18,7 @@ public class PyClassNameCompletionTest extends PyTestCase { } public void testQualified() { - final PyCodeInsightSettings settings = PyCodeInsightSettings.getInstance(); - boolean oldValue = settings.PREFER_FROM_IMPORT; - settings.PREFER_FROM_IMPORT = false; - try { - doTest(); - } - finally { - settings.PREFER_FROM_IMPORT = oldValue; - } + doTestWithoutFromImport(); } public void testFunction() { @@ -45,6 +37,22 @@ public class PyClassNameCompletionTest extends PyTestCase { doTest(); } + public void testSubmoduleRegularImport() { // PY-7887 + doTestWithoutFromImport(); + } + + private void doTestWithoutFromImport() { + final PyCodeInsightSettings settings = PyCodeInsightSettings.getInstance(); + boolean oldValue = settings.PREFER_FROM_IMPORT; + settings.PREFER_FROM_IMPORT = false; + try { + doTest(); + } + finally { + settings.PREFER_FROM_IMPORT = oldValue; + } + } + private void doTest() { final String path = "/completion/className/" + getTestName(true); myFixture.copyDirectoryToProject(path, ""); From 6d1b33c63421a68b26bb88ec4a0a6cb7a274713e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 21:19:04 +0100 Subject: [PATCH 18/54] auto-import fix for module uses correct qualified name (PY-6677) --- .../codeInsight/imports/ImportFromExistingAction.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java index fb639a875289..dd6ca8c68616 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java @@ -135,7 +135,11 @@ public class ImportFromExistingAction implements QuestionAction { else { String qualifiedName = item.getPath().toString(); if (myUseQualifiedImport) { - AddImportHelper.addImportStatement(file, qualifiedName, null, priority); + String nameToImport = qualifiedName; + if (item.getImportable() instanceof PsiFileSystemItem) { + nameToImport += "." + myName; + } + AddImportHelper.addImportStatement(file, nameToImport, null, priority); myTarget.replace(gen.createExpressionFromText(LanguageLevel.forElement(myTarget), qualifiedName + "." + myName)); } else { From 0b9c257ad2504061f22fde2c90aafd85440429e7 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 5 Feb 2013 21:27:39 +0100 Subject: [PATCH 19/54] add import element before end-of-line comment (PY-8034) --- .../psi/impl/PyFromImportStatementImpl.java | 10 +++++++--- python/testData/addImport/comment.after.py | 1 + python/testData/addImport/comment.py | 1 + .../com/jetbrains/python/PyAddImportTest.java | 16 ++++++++++++---- .../jetbrains/python/PythonAllTestsSuite.java | 3 ++- 5 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 python/testData/addImport/comment.after.py create mode 100644 python/testData/addImport/comment.py diff --git a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java index 4f98700bfccf..45877d1cfd57 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java @@ -161,9 +161,13 @@ public class PyFromImportStatementImpl extends PyBaseElementImpl Date: Wed, 6 Feb 2013 16:37:56 +0400 Subject: [PATCH 20/54] Reverted default value of unknown objects to None (PY-8703) This reverts the effects of 16a8636bae4c5ac2ef5ab21e3a155adadd00e1ad, so a new fix for PY-7340 is required. --- python/helpers/generator3.py | 6 +++--- python/helpers/required_gen_version | 4 ++-- .../python/psi/types/PyTypeChecker.java | 17 +++++------------ 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py index 0ae7b6e1aa9e..4cbbb9bfd457 100644 --- a/python/helpers/generator3.py +++ b/python/helpers/generator3.py @@ -24,7 +24,7 @@ but seemingly no one uses them in C extensions yet anyway. # * re.search-bound, ~30% time, in likes of builtins and _gtk with complex docstrings. # None of this can seemingly be easily helped. Maybe there's a simpler and faster parser library? -VERSION = "1.123" # Must be a number-dot-number string, updated with each change that affects generated skeletons +VERSION = "1.124" # Must be a number-dot-number string, updated with each change that affects generated skeletons # Note: DON'T FORGET TO UPDATE! import sys @@ -1300,7 +1300,7 @@ class ModuleRedeclarator(object): if found_name: if found_name == as_name: notice = " # (!) real value is %r" % s - s = "object()" + s = "None" else: notice = " # (!) forward: %s, real value is %r" % (found_name, s) if SANE_REPR_RE.match(s): @@ -1308,7 +1308,7 @@ class ModuleRedeclarator(object): else: if not found_name: notice = " # (!) real value is %r" % s - out(indent, prefix, "object()", postfix, notice) + out(indent, prefix, "None", postfix, notice) def getRetType(self, s): diff --git a/python/helpers/required_gen_version b/python/helpers/required_gen_version index ae5e26e48e1b..124263039ad3 100644 --- a/python/helpers/required_gen_version +++ b/python/helpers/required_gen_version @@ -6,7 +6,7 @@ (default) 1.92 # anything not explicitly marked -(built-in) 1.123 # skeletons of all built-in modules are built together +(built-in) 1.124 # skeletons of all built-in modules are built together # Note: modules like itertools, etc are "(built-in)" and are ignored if given separately _fileio 1.101 @@ -15,7 +15,7 @@ sys 1.101 thread 1.102 _thread 1.102 _struct 1.103 -datetime 1.121 +datetime 1.124 PyQt4.Qsci 1.94 PyQt4.QtAssistant 1.94 diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index d998ec79dbab..f2d4c91bb80c 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -48,8 +48,11 @@ public class PyTypeChecker { if (expected == null || actual == null) { return true; } - if (isObjectType(expected) || isObjectType(actual)) { - return true; + if (expected instanceof PyClassType) { + final PyClass c = ((PyClassType)expected).getPyClass(); + if (c != null && "object".equals(c.getName())) { + return true; + } } if ((expected instanceof PyTypeReference || actual instanceof PyTypeReference) && !recursive) { return true; @@ -158,16 +161,6 @@ public class PyTypeChecker { return false; } - private static boolean isObjectType(@NotNull PyType type) { - if (type instanceof PyClassType) { - final PyClass c = ((PyClassType)type).getPyClass(); - if ("object".equals(c.getName())) { - return true; - } - } - return false; - } - public static boolean isUnknown(@Nullable PyType type) { if (type == null || type instanceof PyTypeReference || type instanceof PyGenericType) { return true; From 171b464ee2662b01787ddc04565d3608a678fa89 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 15:50:15 +0100 Subject: [PATCH 21/54] List remote interpreter connection in servers list (PY-8589). --- .../jetbrains/python/remote/PyRemoteSdkAdditionalData.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java index eee2a9d72edb..713c56f319d0 100644 --- a/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java +++ b/python/src/com/jetbrains/python/remote/PyRemoteSdkAdditionalData.java @@ -286,9 +286,12 @@ public final class PyRemoteSdkAdditionalData extends PythonSdkAdditionalData imp @Nullable @Override - public Object clone() throws CloneNotSupportedException { + public PyRemoteSdkAdditionalData clone() { try { final PyRemoteSdkAdditionalData copy = (PyRemoteSdkAdditionalData)super.clone(); + if (copy == null) { + return null; + } copyTo(copy); return copy; From 93a6630fb7f2cee4e1824ec996f5ad004b352a61 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 15:54:58 +0100 Subject: [PATCH 22/54] Fixed console for ipython >0.10 (PY-8758). --- python/helpers/pydev/pydev_ipython_console_011.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/pydev/pydev_ipython_console_011.py b/python/helpers/pydev/pydev_ipython_console_011.py index 34cd2371a3a5..da08bd136ab5 100644 --- a/python/helpers/pydev/pydev_ipython_console_011.py +++ b/python/helpers/pydev/pydev_ipython_console_011.py @@ -145,5 +145,5 @@ class PyDevFrontEnd: return self.ipython.automagic def get_greeting_msg(self): - sys.stderr.write('PyDev console: using IPython %s\n' % self.version) + return 'PyDev console: using IPython %s\n' % self.version From f1b3a39207f5266005a09e77bc62e31308daafb3 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 16:06:23 +0100 Subject: [PATCH 23/54] Collecting run-time types information isn't supported for Jython (PY-8737). --- python/helpers/pydev/pydevd.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py index a7476580989c..28880d1a2b5b 100644 --- a/python/helpers/pydev/pydevd.py +++ b/python/helpers/pydev/pydevd.py @@ -1461,7 +1461,10 @@ if __name__ == '__main__': debugger = PyDB() if setup['save-signatures']: - debugger.signature_factory = SignatureFactory() + if pydevd_vm_type.GetVmType() == pydevd_vm_type.PydevdVmType.JYTHON: + sys.stderr.write("Collecting run-time type information is not supported for Jython\n") + else: + debugger.signature_factory = SignatureFactory() debugger.connect(host, port) From a8805931a21931cc24ade1dc7bf2923a1f7cbc1d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 14:28:46 +0100 Subject: [PATCH 24/54] PY-8764 --- python/src/com/jetbrains/python/psi/types/PyTypeChecker.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index d998ec79dbab..fb43fd9a75c7 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -483,6 +483,9 @@ public class PyTypeChecker { if (qualifierType instanceof PyUnionType) { final PyUnionType unionType = (PyUnionType)qualifierType; final String name = callee.getName(); + if (name == null) { + return false; + } int sameNameCount = 0; for (PyType member : unionType.getMembers()) { if (member != null) { From 6fe9a191a284fad8c1655685a23b138c8b04f249 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 14:56:05 +0100 Subject: [PATCH 25/54] @NotNull name in PyType.resolveMember() --- .../com/jetbrains/python/psi/impl/PyJavaClassType.java | 3 ++- .../com/jetbrains/python/psi/impl/PyJavaPackageType.java | 3 ++- .../psi-api/src/com/jetbrains/python/psi/types/PyType.java | 3 ++- .../python/codeInsight/stdlib/PyNamedTupleType.java | 2 +- .../python/psi/impl/references/PyReferenceImpl.java | 5 +++-- .../src/com/jetbrains/python/psi/types/PyClassTypeImpl.java | 2 +- .../src/com/jetbrains/python/psi/types/PyFunctionType.java | 2 +- python/src/com/jetbrains/python/psi/types/PyGenericType.java | 2 +- .../com/jetbrains/python/psi/types/PyImportedModuleType.java | 2 +- python/src/com/jetbrains/python/psi/types/PyModuleType.java | 2 +- python/src/com/jetbrains/python/psi/types/PyNoneType.java | 3 ++- .../com/jetbrains/python/psi/types/PyTypeReferenceImpl.java | 2 +- python/src/com/jetbrains/python/psi/types/PyUnionType.java | 3 ++- 13 files changed, 20 insertions(+), 14 deletions(-) diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index f86d08168b9a..d1667a07eed5 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -12,6 +12,7 @@ import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -27,7 +28,7 @@ public class PyJavaClassType implements PyType { } @Nullable - public List resolveMember(final String name, + public List resolveMember(@NotNull final String name, PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java index a1c4d10ba3ac..977e7d2a3573 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaPackageType.java @@ -16,6 +16,7 @@ import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -34,7 +35,7 @@ public class PyJavaPackageType implements PyType { } @Override - public List resolveMember(String name, + public List resolveMember(@NotNull String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java index fdbac85c3cf3..99075827ef97 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java @@ -6,6 +6,7 @@ import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -31,7 +32,7 @@ public interface PyType { * or a list of elements that define the name, a la multiResolve(). */ @Nullable - List resolveMember(final String name, @Nullable PyExpression location, AccessDirection direction, + List resolveMember(@NotNull final String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext); /** diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java index 2faf7928d249..2c824e67048d 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java @@ -38,7 +38,7 @@ public class PyNamedTupleType extends PyClassTypeImpl implements PyCallableType } @Override - public List resolveMember(String name, + public List resolveMember(@NotNull String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index 2cb1e79ce8b7..cd93c7b64147 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -288,8 +288,9 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference if (uexpr == null) { // ...as a part of current module PyType otype = builtins_cache.getObjectType(); // "object" as a closest kin to "module" - if (otype != null) { - ret.addAll(otype.resolveMember(myElement.getName(), null, AccessDirection.READ, myContext)); + String name = myElement.getName(); + if (otype != null && name != null) { + ret.addAll(otype.resolveMember(name, null, AccessDirection.READ, myContext)); } } if (uexpr == null) { diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 631856cbee4b..0fb2f10830eb 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -91,7 +91,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { } @Nullable - public List resolveMember(final String name, @Nullable PyExpression location, AccessDirection direction, + public List resolveMember(@NotNull final String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { final Set> resolving = ourResolveMemberStack.get(); final Pair key = Pair.create(myClass, name); diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index e66c3a7069bf..8b68d03094a8 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -29,7 +29,7 @@ public class PyFunctionType implements PyCallableType { } @Override - public List resolveMember(String name, + public List resolveMember(@NotNull String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyGenericType.java b/python/src/com/jetbrains/python/psi/types/PyGenericType.java index 27655d3c330c..9c0b0245c764 100644 --- a/python/src/com/jetbrains/python/psi/types/PyGenericType.java +++ b/python/src/com/jetbrains/python/psi/types/PyGenericType.java @@ -22,7 +22,7 @@ public class PyGenericType implements PyType { @Nullable @Override - public List resolveMember(String name, + public List resolveMember(@NotNull String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java index 29b50a8f7c71..42e24077212c 100644 --- a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java @@ -35,7 +35,7 @@ public class PyImportedModuleType implements PyType { @Nullable @Override - public List resolveMember(String name, + public List resolveMember(@NotNull String name, PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java index 70d0d9f23219..6213aef01a37 100644 --- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java @@ -58,7 +58,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje @Nullable @Override - public List resolveMember(final String name, + public List resolveMember(@NotNull final String name, @Nullable PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyNoneType.java b/python/src/com/jetbrains/python/psi/types/PyNoneType.java index 3cacd7a081b8..e34ba6f94c6c 100644 --- a/python/src/com/jetbrains/python/psi/types/PyNoneType.java +++ b/python/src/com/jetbrains/python/psi/types/PyNoneType.java @@ -6,6 +6,7 @@ import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -20,7 +21,7 @@ public class PyNoneType implements PyType { // TODO must extend ClassType. It's } @Nullable - public List resolveMember(final String name, + public List resolveMember(@NotNull final String name, PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeReferenceImpl.java b/python/src/com/jetbrains/python/psi/types/PyTypeReferenceImpl.java index 1d659bdc4a8a..1727ed264e64 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeReferenceImpl.java @@ -20,7 +20,7 @@ import java.util.Set; */ public abstract class PyTypeReferenceImpl implements PyTypeReference { @NotNull - public List resolveMember(String name, + public List resolveMember(@NotNull String name, PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { diff --git a/python/src/com/jetbrains/python/psi/types/PyUnionType.java b/python/src/com/jetbrains/python/psi/types/PyUnionType.java index f22042dbc126..0e1e62873eb0 100644 --- a/python/src/com/jetbrains/python/psi/types/PyUnionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyUnionType.java @@ -8,6 +8,7 @@ import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -23,7 +24,7 @@ public class PyUnionType implements PyType { } @Nullable - public List resolveMember(String name, + public List resolveMember(@NotNull String name, PyExpression location, AccessDirection direction, PyResolveContext resolveContext) { From f00ece8e2f3bb7b3627da0c3da0f259b428509de Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 16:43:53 +0100 Subject: [PATCH 26/54] don't insert docstring with types if we don't have any parameters (PY-8768) --- .../codeInsight/intentions/PyGenerateDocstringIntention.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index b0620d75658e..f0123dc3dfd0 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -108,7 +108,7 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); - if (signature != null) { + if (signature != null && function.getParameterList().getParameters().length > 0) { addFunctionArguments(function, signature, docstringGenerator); From 4c7d6e4f75fed3b65ae0d181e532e081b44d53d2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 16:44:24 +0100 Subject: [PATCH 27/54] workaround for http://bugs.python.org/issue17143 (PY-8706) --- python/helpers/pydev/pydevd_signature.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/helpers/pydev/pydevd_signature.py b/python/helpers/pydev/pydevd_signature.py index 6292360519ce..77559b35ae88 100644 --- a/python/helpers/pydev/pydevd_signature.py +++ b/python/helpers/pydev/pydevd_signature.py @@ -1,5 +1,6 @@ import inspect -from trace import modname +import trace +trace._warn = lambda *args: None # workaround for http://bugs.python.org/issue17143 (PY-8706) import gc from pydevd_comm import CMD_SIGNATURE_CALL_TRACE, NetCommand import pydevd_vars @@ -51,7 +52,7 @@ class SignatureFactory(object): code = frame.f_code filename = code.co_filename if filename: - modulename = modname(filename) + modulename = trace.modname(filename) else: modulename = None From 9c4a398f5042742a9bc39ba50e2e11c29ce19cb3 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 17:10:35 +0100 Subject: [PATCH 28/54] Ask Vagrant executable path if we couldn't get it version (PY-8653). --- .../com/jetbrains/python/sdk/PySdkUtil.java | 21 ------------------- .../python/sdk/flavors/PythonSdkFlavor.java | 5 +++-- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/python/src/com/jetbrains/python/sdk/PySdkUtil.java b/python/src/com/jetbrains/python/sdk/PySdkUtil.java index e046208c72c6..0932a371f69d 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkUtil.java +++ b/python/src/com/jetbrains/python/sdk/PySdkUtil.java @@ -182,27 +182,6 @@ public class PySdkUtil { } } - /** - * Finds the first match in a list os Strings. - * - * @param lines list of lines, may be null. - * @param regex pattern to match to. - * @return pattern's first matched group, or entire matched string if pattern has no groups, or null. - */ - @Nullable - public static String getFirstMatch(List lines, Pattern regex) { - if (lines == null) return null; - for (String s : lines) { - Matcher m = regex.matcher(s); - if (m.matches()) { - if (m.groupCount() > 0) { - return m.group(1); - } - } - } - return null; - } - public static boolean isRemote(@Nullable Sdk sdk) { return sdk != null && sdk.getSdkAdditionalData() instanceof RemoteCredentials; } diff --git a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java index 000f67ba2d8c..09debcfe2889 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java @@ -10,6 +10,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.util.PatternUtil; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.sdk.PySdkUtil; import com.jetbrains.python.sdk.PythonEnvUtil; @@ -173,11 +174,11 @@ public abstract class PythonSdkFlavor { return null; } Pattern pattern = Pattern.compile(version_regexp); - final String result = PySdkUtil.getFirstMatch(process_output.getStderrLines(), pattern); + final String result = PatternUtil.getFirstMatch(process_output.getStderrLines(), pattern); if (result != null) { return result; } - return PySdkUtil.getFirstMatch(process_output.getStdoutLines(), pattern); + return PatternUtil.getFirstMatch(process_output.getStdoutLines(), pattern); } public Collection getExtraDebugOptions() { From d1f61b709e2be7914193e51c3d5fac24880b4f67 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 17:35:47 +0100 Subject: [PATCH 29/54] fix for compatibility with token type caching in PsiBuilder --- .../python/parsing/StatementParsing.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/parsing/StatementParsing.java b/python/src/com/jetbrains/python/parsing/StatementParsing.java index f07e7f8fbfab..37751366a56e 100644 --- a/python/src/com/jetbrains/python/parsing/StatementParsing.java +++ b/python/src/com/jetbrains/python/parsing/StatementParsing.java @@ -66,6 +66,11 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } } + private void setExpectAsKeyword(boolean expectAsKeyword) { + myExpectAsKeyword = expectAsKeyword; + myBuilder.setTokenTypeRemapper(this); // clear cached token type + } + public void parseStatement(ParsingScope scope) { while (myBuilder.getTokenType() == PyTokenTypes.STATEMENT_BREAK) { @@ -472,14 +477,14 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { } } } - myExpectAsKeyword = true; // possible 'as' comes as an ident; reparse it as keyword if found + setExpectAsKeyword(true); // possible 'as' comes as an ident; reparse it as keyword if found if (builder.getTokenType() == PyTokenTypes.AS_KEYWORD) { builder.advanceLexer(); - myExpectAsKeyword = false; + setExpectAsKeyword(false); parseIdentifier(PyElementTypes.TARGET_EXPRESSION); } asMarker.done(elementType); - myExpectAsKeyword = false; + setExpectAsKeyword(false); if (builder.getTokenType() == PyTokenTypes.COMMA) { builder.advanceLexer(); if (in_parens && builder.getTokenType() == PyTokenTypes.RPAR) { @@ -527,14 +532,14 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { myBuilder.advanceLexer(); marker.done(getReferenceType()); boolean old_expect_AS_kwd = myExpectAsKeyword; - myExpectAsKeyword = expect_as; + setExpectAsKeyword(expect_as); while (myBuilder.getTokenType() == PyTokenTypes.DOT) { marker = marker.precede(); myBuilder.advanceLexer(); checkMatches(PyTokenTypes.IDENTIFIER, IDENTIFIER_EXPECTED); marker.done(getReferenceType()); } - myExpectAsKeyword = old_expect_AS_kwd; + setExpectAsKeyword(old_expect_AS_kwd); return true; } @@ -675,7 +680,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { if (!getExpressionParser().parseSingleExpression(false, false)) { myBuilder.error(EXPRESSION_EXPECTED); } - myExpectAsKeyword = true; + setExpectAsKeyword(true); if (myBuilder.getTokenType() == PyTokenTypes.COMMA || myBuilder.getTokenType() == PyTokenTypes.AS_KEYWORD) { myBuilder.advanceLexer(); if (!getExpressionParser().parseSingleExpression(true, false)) { @@ -730,7 +735,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { while (true) { PsiBuilder.Marker withItem = myBuilder.mark(); getExpressionParser().parseExpression(); - myExpectAsKeyword = true; + setExpectAsKeyword(true); if (myBuilder.getTokenType() == PyTokenTypes.AS_KEYWORD) { myBuilder.advanceLexer(); getExpressionParser().parseSingleExpression(true, false); // 'as' is followed by a target From b6550f3ea22f493137fc2c5754400cfbf49786ee Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 17:36:38 +0100 Subject: [PATCH 30/54] extract isInnerComprehension() method --- .../psi/impl/references/PyReferenceImpl.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index cd93c7b64147..0a8a9d2ac584 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -151,19 +151,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference PsiElement definition = instruction.getElement(); NameDefiner definer = null; // TODO: This check may slow down resolving, but it is the current solution to the comprehension scopes problem - final PyComprehensionElement definitionComprehension = PsiTreeUtil.getParentOfType(definition, PyComprehensionElement.class); - if (definitionComprehension != null) { - final boolean isAtLeast30 = LanguageLevel.forElement(definitionComprehension).isAtLeast(LanguageLevel.PYTHON30); - final boolean isListComprehension = definitionComprehension instanceof PyListCompExpression; - if (!isListComprehension || isAtLeast30) { - if (true) { - final PyComprehensionElement elementComprehension = PsiTreeUtil.getParentOfType(element, PyComprehensionElement.class); - if (elementComprehension == null || !PsiTreeUtil.isAncestor(definitionComprehension, elementComprehension, false)) { - continue; - } - } - } - } + if (isInnerComprehension(element, definition)) continue; if (definition instanceof NameDefiner && !(definition instanceof PsiNamedElement)) { definer = (NameDefiner)definition; definition = definer.getElementNamed(name); @@ -201,6 +189,21 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference return results; } + private static boolean isInnerComprehension(PsiElement referenceElement, PsiElement definition) { + final PyComprehensionElement definitionComprehension = PsiTreeUtil.getParentOfType(definition, PyComprehensionElement.class); + if (definitionComprehension != null) { + final boolean isAtLeast30 = LanguageLevel.forElement(definitionComprehension).isAtLeast(LanguageLevel.PYTHON30); + final boolean isListComprehension = definitionComprehension instanceof PyListCompExpression; + if (!isListComprehension || isAtLeast30) { + final PyComprehensionElement elementComprehension = PsiTreeUtil.getParentOfType(referenceElement, PyComprehensionElement.class); + if (elementComprehension == null || !PsiTreeUtil.isAncestor(definitionComprehension, elementComprehension, false)) { + return true; + } + } + } + return false; + } + /** * Does actual resolution of resolve(). * From 6428f1a3a554e9483899e33015bae29301dc163e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 17:47:39 +0100 Subject: [PATCH 31/54] continue name search in upper scopes if the name found in current scope is defined in a comprehension scope and not actually visible from the reference location (PY-8725) --- .../psi/impl/references/PyReferenceImpl.java | 38 +++++++++++-------- python/testData/resolve/GeneratorShadowing.py | 9 +++++ .../com/jetbrains/python/PyResolveTest.java | 4 ++ 3 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 python/testData/resolve/GeneratorShadowing.py diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index 0a8a9d2ac584..af0f251a7ae8 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -144,9 +144,8 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference } @NotNull - private static ResolveResultList resolveToLatestDefs(@NotNull ScopeOwner owner, @NotNull PsiElement element, @NotNull String name) { + private static ResolveResultList resolveToLatestDefs(@NotNull List instructions, @NotNull PsiElement element, @NotNull String name) { final ResolveResultList ret = new ResolveResultList(); - final List instructions = PyDefUseUtil.getLatestDefs(owner, name, element, false); for (ReadWriteInstruction instruction : instructions) { PsiElement definition = instruction.getElement(); NameDefiner definer = null; @@ -191,19 +190,27 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference private static boolean isInnerComprehension(PsiElement referenceElement, PsiElement definition) { final PyComprehensionElement definitionComprehension = PsiTreeUtil.getParentOfType(definition, PyComprehensionElement.class); - if (definitionComprehension != null) { - final boolean isAtLeast30 = LanguageLevel.forElement(definitionComprehension).isAtLeast(LanguageLevel.PYTHON30); - final boolean isListComprehension = definitionComprehension instanceof PyListCompExpression; - if (!isListComprehension || isAtLeast30) { - final PyComprehensionElement elementComprehension = PsiTreeUtil.getParentOfType(referenceElement, PyComprehensionElement.class); - if (elementComprehension == null || !PsiTreeUtil.isAncestor(definitionComprehension, elementComprehension, false)) { - return true; - } + if (definitionComprehension != null && isOwnScopeComprehension(definitionComprehension)) { + final PyComprehensionElement elementComprehension = PsiTreeUtil.getParentOfType(referenceElement, PyComprehensionElement.class); + if (elementComprehension == null || !PsiTreeUtil.isAncestor(definitionComprehension, elementComprehension, false)) { + return true; } } return false; } + private static boolean isOwnScopeComprehension(PsiElement definitionComprehension) { + final boolean isAtLeast30 = LanguageLevel.forElement(definitionComprehension).isAtLeast(LanguageLevel.PYTHON30); + final boolean isListComprehension = definitionComprehension instanceof PyListCompExpression; + return !isListComprehension || isAtLeast30; + } + + private static boolean isInOwnScopeComprehension(PsiElement uexpr) { + PyComprehensionElement comprehensionElement = PsiTreeUtil.getParentOfType(uexpr, PyComprehensionElement.class); + return comprehensionElement != null && isOwnScopeComprehension(comprehensionElement); + } + + /** * Does actual resolution of resolve(). * @@ -251,15 +258,16 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference uexpr = null; } else if (owner == originalOwner && !scope.isGlobal(referencedName)) { - final ResolveResultList latest = resolveToLatestDefs(owner, myElement, referencedName); + final List instructions = PyDefUseUtil.getLatestDefs(owner, referencedName, myElement, false); + final ResolveResultList latest = resolveToLatestDefs(instructions, myElement, referencedName); if (!latest.isEmpty()) { return latest; } - if (owner instanceof PyClass) { - final ScopeOwner classOwner = ScopeUtil.getScopeOwner(owner); - if (classOwner != null) { + if (owner instanceof PyClass || (instructions.isEmpty() && isInOwnScopeComprehension(uexpr))) { + final ScopeOwner parentOwner = ScopeUtil.getScopeOwner(owner); + if (parentOwner != null) { processor = new ResolveProcessor(referencedName); - PyResolveUtil.scopeCrawlUp(processor, classOwner, referencedName, roof); + PyResolveUtil.scopeCrawlUp(processor, parentOwner, referencedName, roof); uexpr = processor.getResult(); } } diff --git a/python/testData/resolve/GeneratorShadowing.py b/python/testData/resolve/GeneratorShadowing.py new file mode 100644 index 000000000000..eea177c5542f --- /dev/null +++ b/python/testData/resolve/GeneratorShadowing.py @@ -0,0 +1,9 @@ +def _(arg): + print(arg) + +def foo(): + _("foo") # This call is underlined by the inspector as an unresolved reference +# + print("\n".join("bar" for _ in range(5))) + +foo() diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java index b79ca31463df..10150deef82d 100644 --- a/python/testSrc/com/jetbrains/python/PyResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java @@ -521,4 +521,8 @@ public class PyResolveTest extends PyResolveTestCase { assertEquals("foo", res.getName()); assertInstanceOf(res.getParent(), PyAugAssignmentStatement.class); } + + public void testGeneratorShadowing() { // PY-8725 + assertResolvesTo(PyFunction.class, "_"); + } } From 627b6b70adfc8303ca57455cd29924482ef4aa39 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 6 Feb 2013 20:53:56 +0400 Subject: [PATCH 32/54] Resolve library modules first, then ask import resolver extensions (PY-8664) The problem in PY-8664 was probably in resolving to posix/__init__.pxd instead of /posix.py. --- .../python/psi/resolve/QualifiedNameResolverImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java index 4b786de3e974..51839aa1f6bf 100644 --- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java +++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java @@ -201,6 +201,9 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso addResultsFromRoots(); } + mySourceResults.addAll(myLibResults); + myLibResults.clear(); + if (!myWithoutForeign) { for (PyImportResolver resolver : Extensions.getExtensions(PyImportResolver.EP_NAME)) { PsiElement foreign = resolver.resolveImportReference(myQualifiedName, myContext); @@ -210,9 +213,6 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso } } - mySourceResults.addAll(myLibResults); - myLibResults.clear(); - return Lists.newArrayList(mySourceResults); } From 5716bb19dd50c47442ecdc6ad089e4a239ccd045 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 18:03:02 +0100 Subject: [PATCH 33/54] Fixed search in settings (PY-8658). --- python/build/pycharm_build.gant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/build/pycharm_build.gant b/python/build/pycharm_build.gant index 87780f74d65f..c9ef216cb3a4 100644 --- a/python/build/pycharm_build.gant +++ b/python/build/pycharm_build.gant @@ -103,7 +103,7 @@ target('default': "Build artifacts") { def usedJars = buildModules(modules, ["python/lib", "plugins/coverage-common/lib"]) buildSearchableOptions("${projectBuilder.moduleOutput(findModule("platform-resources"))}/search", ["$home/build/idea.license", "$home/build/pycharm.license"], { - projectBuilder.moduleRuntimeClasspath(findModule("python-ide"), false).each { + projectBuilder.moduleRuntimeClasspath(findModule("main_pycharm"), false).each { pathelement(location: it) } }, "-Didea.platform.prefix=Python -Didea.no.jre.check=true") From 8aff6e583059593a09c5f6ac36d50f03d821e6d4 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 6 Feb 2013 23:30:55 +0400 Subject: [PATCH 34/54] Clear package caches after installing package management tools (PY-8739) --- .../src/com/jetbrains/python/packaging/PyPackageManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java index cc870bc2de18..bbee80818bea 100644 --- a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java +++ b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java @@ -317,6 +317,7 @@ public class PyPackageManagerImpl extends PyPackageManager { } } finally { + clearCaches(); FileUtil.delete(new File(dirName)); //TODO: remove temp directory for remote interpreter } } From f57562e8021d2e57bb3744e032c24f0dca2171ab Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 20:32:05 +0100 Subject: [PATCH 35/54] Collect types information for remote interpreters (PY-8733). --- .../python/debugger/PyPositionConverter.java | 1 - .../python/debugger/PySignature.java | 25 +++++++++++++------ .../python/debugger/pydev/ProtocolParser.java | 2 +- .../python/debugger/PyDebugProcess.java | 9 +++++-- .../debugger/PySignatureCacheManagerImpl.java | 4 +-- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyPositionConverter.java b/python/pydevSrc/com/jetbrains/python/debugger/PyPositionConverter.java index 0b5098bfd3ef..2b44f9d9ff99 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyPositionConverter.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyPositionConverter.java @@ -15,5 +15,4 @@ public interface PyPositionConverter { @Nullable XSourcePosition convertFromPython(@NotNull final PySourcePosition position); - } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java index 6d1bd1b85037..82a97e1eff4e 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java @@ -1,13 +1,11 @@ package com.jetbrains.python.debugger; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Map; /** * @author traff @@ -17,7 +15,6 @@ public class PySignature { private final String myFunctionName; private final List myArgs = Lists.newArrayList(); - private final Map myTypeMap = Maps.newHashMap(); public PySignature(@NotNull String file, @NotNull String name) { myFile = file; @@ -26,7 +23,12 @@ public class PySignature { @Nullable public String getArgTypeQualifiedName(String name) { - return myTypeMap.get(name); + for (NamedParameter param : myArgs) { + if (name.equals(param.getName())) { + return param.getTypeQualifiedName(); + } + } + return null; } @NotNull @@ -45,12 +47,15 @@ public class PySignature { } @NotNull - public PySignature merge(@NotNull PySignature signature) { + public PySignature addAllArgs(@NotNull PySignature signature) { for (NamedParameter param : signature.getArgs()) { NamedParameter ourParam = getArgForName(param.getName()); if (ourParam != null) { ourParam.addTypes(param.getTypesList()); } + else { + addArgument(param); + } } return this; } @@ -113,9 +118,13 @@ public class PySignature { } } - public PySignature addArgumentVar(String name, String type) { - myArgs.add(new NamedParameter(name, type)); - myTypeMap.put(name, type); + + public PySignature addArgument(String name, String type) { + return addArgument(new NamedParameter(name, type)); + } + + public PySignature addArgument(NamedParameter argument) { + myArgs.add(argument); return this; } } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java index c32106bfdbdf..f487b4a3b218 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java @@ -34,7 +34,7 @@ public class ProtocolParser { if (!"arg".equals(reader.getNodeName())) { throw new PyDebuggerException("Expected , found " + reader.getNodeName()); } - signature.addArgumentVar(readString(reader, "name", ""), readString(reader, "type", "")); + signature.addArgument(readString(reader, "name", ""), readString(reader, "type", "")); reader.moveUp(); } diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 787e27f44b36..2748b24664fe 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -250,6 +250,11 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr @Override public void recordSignature(PySignature signature) { + if (myPositionConverter instanceof PyRemotePositionConverter) { + String localPath = ((PyRemotePositionConverter)myPositionConverter).getPathMappingSettings().convertToLocal(signature.getFile()); + signature = new PySignature(localPath, signature.getFunctionName()).addAllArgs(signature); + } + PySignatureCacheManager.getInstance(getSession().getProject()).recordSignature(signature); } @@ -612,8 +617,8 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr if (myProcessHandler instanceof PythonProcessHandler) { ((PythonProcessHandler)myProcessHandler) .setShouldTryToKillSoftly(false); //while process is suspended it can't terminate softly, - //multiple processes in debug mode also can not terminate properly - //so its better to kill all the tree in a hard way + //multiple processes in debug mode also can not terminate properly + //so its better to kill all the tree in a hard way } } diff --git a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java index 0325dc661c08..a44c56c7451d 100644 --- a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java +++ b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java @@ -78,7 +78,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { else { //noinspection ConstantConditions lines[i] = signatureToString(stringToSignature(file. - getCanonicalPath(), lines[i]).merge(signature)); + getCanonicalPath(), lines[i]).addAllArgs(signature)); } } i++; @@ -198,7 +198,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { for (int i = 1; i < parts.length; i++) { String[] var = parts[i].split(":"); if (var.length == 2) { - signature = signature.addArgumentVar(var[0], var[1]); + signature = signature.addArgument(var[0], var[1]); } else { throw new IllegalStateException("Should be : format. " + parts[i] + " instead."); From 433876cc005bb8e3360c1af6575d040ca65d8ad0 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 20:42:54 +0100 Subject: [PATCH 36/54] Don't generate docstring param for self (PY-8759). --- .../intentions/PyGenerateDocstringIntention.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index f0123dc3dfd0..2f9b00b3316d 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -84,10 +84,17 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { private static void addFunctionArguments(PyFunction function, PySignature signature, PyDocstringGenerator docstringGenerator) { for (PySignature.NamedParameter param : signature.getArgs()) { - docstringGenerator.withParamTypedByQualifiedName("type", param.getName(), param.getTypeQualifiedName(), function); + if (!isSelfArgument(param)) { + docstringGenerator.withParamTypedByQualifiedName("type", param.getName(), param.getTypeQualifiedName(), function); + } } } + private static boolean isSelfArgument(PySignature.NamedParameter param) { + //TODO: take in account whether it is a method and param is the first argument + return "self".equals(param.getName()); + } + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) { return; From 053674c9e9beb3971aa582241ee4d765a3292a44 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 20:50:32 +0100 Subject: [PATCH 37/54] Project scope is taken from a better place. --- .../jetbrains/python/debugger/PySignatureCacheManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java index a44c56c7451d..9a235c26a525 100644 --- a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java +++ b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java @@ -13,6 +13,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.ProjectScopeBuilder; import com.jetbrains.django.util.VirtualFileUtil; import com.jetbrains.python.psi.PyClass; @@ -41,7 +42,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { @Override public void recordSignature(@NotNull PySignature signature) { - GlobalSearchScope scope = ProjectScopeBuilder.getInstance(myProject).buildProjectScope(); + GlobalSearchScope scope = ProjectScope.getProjectScope(myProject); VirtualFile file = getFile(signature); if (file != null && scope.contains(file)) { From 81694963e35e51372dcdc95c6764c636de5c24ec Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 18:51:37 +0100 Subject: [PATCH 38/54] use ScopeUtil.getScopeOwner() --- .../com/jetbrains/python/psi/types/PyImportedModuleType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java index 42e24077212c..fd4b93f5f7fe 100644 --- a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java @@ -4,9 +4,9 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyFile; @@ -53,7 +53,7 @@ public class PyImportedModuleType implements PyType { public Object[] getCompletionVariants(String completionPrefix, PyExpression location, ProcessingContext context) { List result = new ArrayList(); - ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(location, ScopeOwner.class); + ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(location); assert scopeOwner != null; final List importTargets = PyModuleType.getVisibleImports(scopeOwner); final int imported = myImportedModule.getImportedPrefix().getComponentCount(); From a2ab96d619694f25b8af5999a19cd906e26daccf Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Feb 2013 21:08:57 +0100 Subject: [PATCH 39/54] PyParameter.isSelf(); highlight first argument of @classmethod as self (PY-6881) --- .../com/jetbrains/python/psi/PyParameter.java | 6 ++++ .../PyUnusedLocalInspectionVisitor.java | 12 ++----- .../python/psi/impl/PyNamedParameterImpl.java | 29 +++++++++++++++-- .../psi/impl/PySingleStarParameterImpl.java | 5 +++ .../python/psi/impl/PyTupleParameterImpl.java | 5 +++ .../validation/HighlightingAnnotator.java | 31 ++----------------- 6 files changed, 48 insertions(+), 40 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyParameter.java b/python/psi-api/src/com/jetbrains/python/psi/PyParameter.java index 123505596fca..a63d47be38f5 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyParameter.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyParameter.java @@ -26,4 +26,10 @@ public interface PyParameter extends PyElement { PyExpression getDefaultValue(); boolean hasDefaultValue(); + + /** + * @return true if the parameter is the 'self' parameter of an instance attribute function or a function + * annotated with @classmethod + */ + boolean isSelf(); } diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java index 1454a9c19f42..5aae8e6ec16b 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java @@ -247,15 +247,9 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { ? (PyNamedParameter) element : (PyNamedParameter) element.getParent(); name = namedParameter.getName(); - if (PsiTreeUtil.getParentOfType(element, PyClass.class) != null) { - // When function is inside a class, first parameter may be either self or cls which is always 'used'. - final PyFunction method = PsiTreeUtil.getParentOfType(element, PyFunction.class); - if (method != null && method.getModifier() != PyFunction.Modifier.STATICMETHOD) { - final PsiElement parent = namedParameter.getParent(); - if (parent instanceof PyParameterList && ((PyParameterList)parent).getParameters()[0] == namedParameter) { - continue; - } - } + // When function is inside a class, first parameter may be either self or cls which is always 'used'. + if (namedParameter.isSelf()) { + continue; } if (myIgnoreLambdaParameters && PsiTreeUtil.getParentOfType(element, Callable.class) instanceof PyLambdaExpression) { continue; diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java index 7f16c71e37a3..1ebeec40f793 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java @@ -9,6 +9,7 @@ import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; +import com.jetbrains.cython.psi.CythonClass; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; @@ -157,11 +158,10 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl Date: Wed, 6 Feb 2013 21:30:55 +0100 Subject: [PATCH 40/54] Added a cache for collecting signatures. --- .../debugger/PySignatureCacheManagerImpl.java | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java index 9a235c26a525..2876b5a459b1 100644 --- a/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java +++ b/python/src/com/jetbrains/python/debugger/PySignatureCacheManagerImpl.java @@ -1,5 +1,8 @@ package com.jetbrains.python.debugger; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import com.google.common.collect.Lists; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -14,7 +17,7 @@ import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; -import com.intellij.psi.search.ProjectScopeBuilder; +import com.intellij.util.ArrayUtil; import com.jetbrains.django.util.VirtualFileUtil; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; @@ -23,6 +26,8 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; /** * @author traff @@ -36,6 +41,17 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { private final Project myProject; + private final LoadingCache mySignatureCache = CacheBuilder.newBuilder() + .maximumSize(1000) + .expireAfterAccess(10, TimeUnit.MINUTES) + .build( + new CacheLoader() { + @Override + public String load(VirtualFile key) throws Exception { + return readAttributeFromFile(key); + } + }); + public PySignatureCacheManagerImpl(Project project) { myProject = project; } @@ -50,21 +66,15 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { } } - private static void recordSignature(VirtualFile file, PySignature signature) { - byte[] data; - try { - data = CALL_SIGNATURES_ATTRIBUTE.readAttributeBytes(file); - } - catch (Exception e) { - data = null; - } + private void recordSignature(VirtualFile file, PySignature signature) { + String dataString = readAttribute(file); String[] lines; - if (data != null) { - lines = (new String(data)).split("\n"); + if (dataString != null) { + lines = dataString.split("\n"); } else { - lines = new String[0]; + lines = ArrayUtil.EMPTY_STRING_ARRAY; } boolean found = false; @@ -97,7 +107,15 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { writeAttribute(file, attrString); } - private static void writeAttribute(@NotNull VirtualFile file, @NotNull String attrString) { + private void writeAttribute(@NotNull VirtualFile file, @NotNull String attrString) { + String cachedValue = mySignatureCache.asMap().get(file); + if (!attrString.equals(cachedValue)) { + mySignatureCache.put(file, attrString); + writeAttributeToAFile(file, attrString); + } + } + + private static void writeAttributeToAFile(@NotNull VirtualFile file, @NotNull String attrString) { try { CALL_SIGNATURES_ATTRIBUTE.writeAttributeBytes(file, attrString.getBytes()); } @@ -154,7 +172,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { } @Nullable - private static PySignature readSignatureAttributeFromFile(@NotNull VirtualFile file, @NotNull String name) { + private PySignature readSignatureAttributeFromFile(@NotNull VirtualFile file, @NotNull String name) { String content = readAttribute(file); if (content != null) { @@ -171,7 +189,21 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { } @Nullable - private static String readAttribute(VirtualFile file) { + private String readAttribute(@NotNull VirtualFile file) { + try { + String attrContent = mySignatureCache.get(file); + if (!StringUtil.isEmpty(attrContent)) { + return attrContent; + } + } + catch (ExecutionException e) { + //pass + } + return null; + } + + @NotNull + private static String readAttributeFromFile(@NotNull VirtualFile file) { byte[] data; try { data = CALL_SIGNATURES_ATTRIBUTE.readAttributeBytes(file); @@ -187,7 +219,7 @@ public class PySignatureCacheManagerImpl extends PySignatureCacheManager { else { content = null; } - return content; + return content != null ? content : ""; } From 95ac0b97ba73e4665b9dbabe00d245cbabaa40af Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 21:50:36 +0100 Subject: [PATCH 41/54] Better checking whether parameter is self. --- .../intentions/PyGenerateDocstringIntention.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index 2f9b00b3316d..6cdbf98ec2b5 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -14,6 +14,7 @@ import com.jetbrains.python.debugger.PySignatureCacheManager; import com.jetbrains.python.documentation.PyDocstringGenerator; import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.PyParameter; import com.jetbrains.python.psi.PyStatementList; import com.jetbrains.python.psi.PyUtil; import org.jetbrains.annotations.NotNull; @@ -84,17 +85,13 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { private static void addFunctionArguments(PyFunction function, PySignature signature, PyDocstringGenerator docstringGenerator) { for (PySignature.NamedParameter param : signature.getArgs()) { - if (!isSelfArgument(param)) { + PyParameter functionParameter = function.getParameterList().findParameterByName(param.getName()); + if (functionParameter != null && !functionParameter.isSelf()) { docstringGenerator.withParamTypedByQualifiedName("type", param.getName(), param.getTypeQualifiedName(), function); } } } - private static boolean isSelfArgument(PySignature.NamedParameter param) { - //TODO: take in account whether it is a method and param is the first argument - return "self".equals(param.getName()); - } - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) { return; From a93b58b45b713ebac5422399ef443b3b16712ae9 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 21:55:15 +0100 Subject: [PATCH 42/54] Generate docstring: remote unnecessary limit for params > 0. --- .../jetbrains/python/documentation/PyDocstringGenerator.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 3275bd13102f..5d9a2c9010e8 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -218,10 +218,6 @@ public class PyDocstringGenerator { int i = 0; - if (paramsToAdd.size() == 0) { - throw new IllegalArgumentException("At least one parameter should be added"); - } - for (DocstringParam param : paramsToAdd) { replacementText.append(getPrefix()); replacementText.append(param.getKind()); From 405643827ba2152f3dc673c32954e50fa699a135 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:32:16 +0100 Subject: [PATCH 43/54] Generate docstring intention: simplified and fixed. --- .../com/jetbrains/python/PyBundle.properties | 3 +- .../PyGenerateDocstringIntention.java | 78 ++++++++++--------- .../SpecifyTypeInDocstringIntention.java | 13 ++-- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index bb1ec26f164d..60fda20373fa 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -192,8 +192,7 @@ INTN.doc.string.stub=Insert documentation string stub #SpecifyTypeInDocstringIntention INTN.specify.type=Specify type for reference in docstring INTN.specify.return.type=Specify return type in docstring -INTN.generate.docstring.with.types=Insert documentation string with types -INTN.add.types.to.docstring=Add dynamically inferred types to docstring +INTN.add.parameters.to.docstring=Add parameters to docstring #SpecifyTypeInPy3AnnotationsIntention INTN.specify.type.in.annotation=Specify type for reference using annotation diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index 6cdbf98ec2b5..24e42b1aac98 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -4,6 +4,7 @@ import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; @@ -15,9 +16,9 @@ import com.jetbrains.python.documentation.PyDocstringGenerator; import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.PyParameter; -import com.jetbrains.python.psi.PyStatementList; import com.jetbrains.python.psi.PyUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * User: catherine @@ -25,7 +26,7 @@ import org.jetbrains.annotations.NotNull; * (with checked format) */ public class PyGenerateDocstringIntention extends BaseIntentionAction { - private String myText = PyBundle.message("INTN.doc.string.stub"); + private String myText; @NotNull public String getFamilyName() { @@ -51,43 +52,50 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { } private boolean isAvailableForFunction(Project project, PsiElement elementAt, PyFunction function) { - PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); - if (signature != null) { - if (function.getDocStringValue() != null) { - PyDocstringGenerator docstringGenerator = new PyDocstringGenerator(function); - addFunctionArguments(function, signature, docstringGenerator); + if (function.getDocStringValue() != null) { + PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); + + PyDocstringGenerator docstringGenerator = new PyDocstringGenerator(function); + addFunctionArguments(function, signature, docstringGenerator); - if (docstringGenerator.haveParametersToAdd()) { - myText = PyBundle.message("INTN.add.types.to.docstring"); - return true; - } + if (docstringGenerator.haveParametersToAdd()) { + myText = PyBundle.message("INTN.add.parameters.to.docstring"); + return true; } else { - myText = PyBundle.message("INTN.generate.docstring.with.types"); - return true; - } - } - - PyStatementList list = PsiTreeUtil.getParentOfType(elementAt, PyStatementList.class, - false, PyFunction.class); - if (list == null) { - if (function.getDocStringExpression() != null) { return false; } - final PyStatementList statementList = function.getStatementList(); - if (statementList != null && statementList.getStatements().length != 0) { - return true; - } } - return false; + else { + myText = PyBundle.message("INTN.doc.string.stub"); + return true; + } } - private static void addFunctionArguments(PyFunction function, PySignature signature, PyDocstringGenerator docstringGenerator) { - for (PySignature.NamedParameter param : signature.getArgs()) { - PyParameter functionParameter = function.getParameterList().findParameterByName(param.getName()); - if (functionParameter != null && !functionParameter.isSelf()) { - docstringGenerator.withParamTypedByQualifiedName("type", param.getName(), param.getTypeQualifiedName(), function); + private static void addFunctionArguments(@NotNull PyFunction function, + @Nullable PySignature signature, + @NotNull PyDocstringGenerator docstringGenerator) { + for (PyParameter functionParam : function.getParameterList().getParameters()) { + if (!functionParam.isSelf()) { + String paramName = functionParam.getName(); + if (!StringUtil.isEmpty(paramName)) { + assert paramName != null; + + String type; + if (signature != null) { + type = signature.getArgTypeQualifiedName(paramName); + } + else { + type = null; + } + if (type != null) { + docstringGenerator.withParamTypedByQualifiedName("type", paramName, type, function); + } + else { + docstringGenerator.withParam("param", paramName); + } + } } } } @@ -112,14 +120,8 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); - if (signature != null && function.getParameterList().getParameters().length > 0) { + addFunctionArguments(function, signature, docstringGenerator); - addFunctionArguments(function, signature, docstringGenerator); - - docstringGenerator.build(); - } - else { - PythonDocumentationProvider.insertDocStub(function, project, editor); - } + docstringGenerator.build(); } } diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java index 0bf0ba965623..65cf4ae21fea 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInDocstringIntention.java @@ -35,21 +35,22 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { PsiElement elementAt = PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset()); PyExpression problemElement = getProblemElement(elementAt); - PsiReference reference = problemElement == null? null : problemElement.getReference(); + PsiReference reference = problemElement == null ? null : problemElement.getReference(); - final PsiElement resolved = reference != null? reference.resolve() : null; + final PsiElement resolved = reference != null ? reference.resolve() : null; PyParameter parameter = getParameter(problemElement, resolved); - String kind = parameter != null? "type" : "rtype"; + String kind = parameter != null ? "type" : "rtype"; final Callable callable = getCallable(elementAt); - if (callable instanceof PyFunction) + if (callable instanceof PyFunction) { generateDocstring(kind, (PyFunction)callable, problemElement); + } } private static void generateDocstring(String kind, PyFunction pyFunction, PyExpression problemElement) { - String name = "rtype".equals(kind)? "" : StringUtil.notNullize(problemElement.getName()); + String name = "rtype".equals(kind) ? "" : StringUtil.notNullize(problemElement.getName()); PyDocstringGenerator docstringGenerator = new PyDocstringGenerator(pyFunction); @@ -67,6 +68,6 @@ public class SpecifyTypeInDocstringIntention extends TypeIntention { @Override protected void updateText(boolean isReturn) { - myText = isReturn? PyBundle.message("INTN.specify.return.type") : PyBundle.message("INTN.specify.type"); + myText = isReturn ? PyBundle.message("INTN.specify.return.type") : PyBundle.message("INTN.specify.type"); } } \ No newline at end of file From ed5090aae2600c6c6ebe6cc25782dfd02e7c4272 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:32:33 +0100 Subject: [PATCH 44/54] @NotNull. --- python/pydevSrc/com/jetbrains/python/debugger/PySignature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java index 82a97e1eff4e..a75887aba711 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java @@ -22,7 +22,7 @@ public class PySignature { } @Nullable - public String getArgTypeQualifiedName(String name) { + public String getArgTypeQualifiedName(@NotNull String name) { for (NamedParameter param : myArgs) { if (name.equals(param.getName())) { return param.getTypeQualifiedName(); From 383b75caa0172ade02b1012f9464e0e89793b167 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:34:58 +0100 Subject: [PATCH 45/54] Cleanup conditions. --- .../PyGenerateDocstringIntention.java | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index 24e42b1aac98..88a764d330ed 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -77,24 +77,22 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { @Nullable PySignature signature, @NotNull PyDocstringGenerator docstringGenerator) { for (PyParameter functionParam : function.getParameterList().getParameters()) { - if (!functionParam.isSelf()) { - String paramName = functionParam.getName(); - if (!StringUtil.isEmpty(paramName)) { - assert paramName != null; + String paramName = functionParam.getName(); + if (!functionParam.isSelf() && !StringUtil.isEmpty(paramName)) { + assert paramName != null; - String type; - if (signature != null) { - type = signature.getArgTypeQualifiedName(paramName); - } - else { - type = null; - } - if (type != null) { - docstringGenerator.withParamTypedByQualifiedName("type", paramName, type, function); - } - else { - docstringGenerator.withParam("param", paramName); - } + String type; + if (signature != null) { + type = signature.getArgTypeQualifiedName(paramName); + } + else { + type = null; + } + if (type != null) { + docstringGenerator.withParamTypedByQualifiedName("type", paramName, type, function); + } + else { + docstringGenerator.withParam("param", paramName); } } } From f85f8af8cc79650acf4779babdbe91693ef1b26b Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:35:48 +0100 Subject: [PATCH 46/54] Cleanup conditions 2. --- .../intentions/PyGenerateDocstringIntention.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index 88a764d330ed..be5cf87629b8 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -81,13 +81,8 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { if (!functionParam.isSelf() && !StringUtil.isEmpty(paramName)) { assert paramName != null; - String type; - if (signature != null) { - type = signature.getArgTypeQualifiedName(paramName); - } - else { - type = null; - } + String type = signature != null ? signature.getArgTypeQualifiedName(paramName) : null; + if (type != null) { docstringGenerator.withParamTypedByQualifiedName("type", paramName, type, function); } From e13cee9bb7358f564aeebbff9abd4c512391f995 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:41:12 +0100 Subject: [PATCH 47/54] Method moved to class. --- .../PyGenerateDocstringIntention.java | 33 +++---------------- .../documentation/PyDocstringGenerator.java | 20 +++++++++++ 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index be5cf87629b8..b8562c318a87 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -4,7 +4,6 @@ import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; @@ -13,12 +12,9 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.debugger.PySignature; import com.jetbrains.python.debugger.PySignatureCacheManager; import com.jetbrains.python.documentation.PyDocstringGenerator; -import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.psi.PyParameter; import com.jetbrains.python.psi.PyUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * User: catherine @@ -48,15 +44,16 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { if (function == null) { return false; } - return isAvailableForFunction(project, elementAt, function); + return isAvailableForFunction(project, function); } - private boolean isAvailableForFunction(Project project, PsiElement elementAt, PyFunction function) { + private boolean isAvailableForFunction(Project project, PyFunction function) { if (function.getDocStringValue() != null) { PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); PyDocstringGenerator docstringGenerator = new PyDocstringGenerator(function); - addFunctionArguments(function, signature, docstringGenerator); + + docstringGenerator.addFunctionArguments(function, signature); if (docstringGenerator.haveParametersToAdd()) { @@ -73,26 +70,6 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { } } - private static void addFunctionArguments(@NotNull PyFunction function, - @Nullable PySignature signature, - @NotNull PyDocstringGenerator docstringGenerator) { - for (PyParameter functionParam : function.getParameterList().getParameters()) { - String paramName = functionParam.getName(); - if (!functionParam.isSelf() && !StringUtil.isEmpty(paramName)) { - assert paramName != null; - - String type = signature != null ? signature.getArgTypeQualifiedName(paramName) : null; - - if (type != null) { - docstringGenerator.withParamTypedByQualifiedName("type", paramName, type, function); - } - else { - docstringGenerator.withParam("param", paramName); - } - } - } - } - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) { return; @@ -113,7 +90,7 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); - addFunctionArguments(function, signature, docstringGenerator); + docstringGenerator.addFunctionArguments(function, signature); docstringGenerator.build(); } diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 5d9a2c9010e8..7702a9c487f3 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyNames; import com.jetbrains.python.PythonFileType; +import com.jetbrains.python.debugger.PySignature; import com.jetbrains.python.debugger.PySignatureUtil; import com.jetbrains.python.psi.*; import org.jetbrains.annotations.NotNull; @@ -60,6 +61,25 @@ public class PyDocstringGenerator { myFile = myDocStringOwner.getContainingFile(); } + public void addFunctionArguments(@NotNull PyFunction function, + @Nullable PySignature signature) { + for (PyParameter functionParam : function.getParameterList().getParameters()) { + String paramName = functionParam.getName(); + if (!functionParam.isSelf() && !StringUtil.isEmpty(paramName)) { + assert paramName != null; + + String type = signature != null ? signature.getArgTypeQualifiedName(paramName) : null; + + if (type != null) { + withParamTypedByQualifiedName("type", paramName, type, function); + } + else { + withParam("param", paramName); + } + } + } + } + public PyDocstringGenerator withParam(@NotNull String kind, @NotNull String name) { return withParamTypedByName(kind, name, null); } From b502cd251a6c1c95e1a96439680122c2a3b2e876 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Wed, 6 Feb 2013 22:42:07 +0100 Subject: [PATCH 48/54] Todo about caching. --- .../jetbrains/python/documentation/PyDocstringGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 7702a9c487f3..7b7ab6d4d959 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -160,7 +160,7 @@ public class PyDocstringGenerator { private Collection collectParametersToAdd() { String text = getDocstringText(); - StructuredDocString structuredDocString = StructuredDocString.parse(text); + StructuredDocString structuredDocString = StructuredDocString.parse(text); //TODO: do we need to cache it? return getParamsToAdd(structuredDocString, myParams); } From 68ef97492b81900ab86228de2c273be5841f684b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 7 Feb 2013 12:02:26 +0100 Subject: [PATCH 49/54] 24-bit instead of 32-bit bmp (PY-8777) --- python/build/resources/logo.bmp | Bin 206038 -> 154542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/python/build/resources/logo.bmp b/python/build/resources/logo.bmp index 7959278c30c93c3600cd27c4c0ba7ed7b2e0798a..a0f246d7419fd78432e3958ec7e3b7a0db6491e8 100644 GIT binary patch literal 154542 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 literal 206038 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 From 177134e892a8e69208eac86d577a2899cf1f382b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 7 Feb 2013 12:12:41 +0100 Subject: [PATCH 50/54] 24-bit instead of 32-bit bmp (PY-8777), now for the correct image --- python/build/resources/logo.bmp | Bin 154542 -> 154542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/python/build/resources/logo.bmp b/python/build/resources/logo.bmp index a0f246d7419fd78432e3958ec7e3b7a0db6491e8..d696a69184643f8da2b750f139ca0852b3c57fa6 100644 GIT binary patch literal 154542 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 From 458b7ae0f15a8fd3349fd7ec6603d8a85d86cf96 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 7 Feb 2013 12:35:36 +0100 Subject: [PATCH 51/54] struggling with line breaks in generated docstrings --- .../jetbrains/python/documentation/PyDocstringGenerator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 7b7ab6d4d959..9835917f34fc 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -234,6 +234,10 @@ public class PyDocstringGenerator { if (replacementText.length() > 0) { replacementText.deleteCharAt(replacementText.length() - 1); } + // if creating a new docstring, leave blank line where text will be entered + if (!StringUtil.containsAlphaCharacters(replacementText.toString())) { + replacementText.append("\n"); + } replacementText.append(ws); int i = 0; From bbc85bd585687c5de57a56da0095b98b6ae16236 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 7 Feb 2013 13:10:29 +0100 Subject: [PATCH 52/54] fix docstring generation tests --- .../intentions/PyGenerateDocstringIntention.java | 3 +++ .../python/documentation/PyDocstringGenerator.java | 13 +++++++++++++ .../documentation/PythonDocumentationProvider.java | 6 ++++++ python/testData/intentions/afterTypeInDocstring.py | 1 + python/testData/intentions/afterTypeInDocstring1.py | 1 + python/testData/intentions/afterTypeInDocstring2.py | 1 + python/testData/intentions/afterTypeInDocstring3.py | 1 + python/testData/intentions/afterTypeInDocstring4.py | 1 + python/testData/intentions/afterTypeInDocstring5.py | 1 + 9 files changed, 28 insertions(+) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java index b8562c318a87..89259692943b 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyGenerateDocstringIntention.java @@ -91,6 +91,9 @@ public class PyGenerateDocstringIntention extends BaseIntentionAction { PySignature signature = PySignatureCacheManager.getInstance(project).findSignature(function); docstringGenerator.addFunctionArguments(function, signature); + if (function.getDocStringValue() == null) { + docstringGenerator.withReturn(); + } docstringGenerator.build(); } diff --git a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java index 9835917f34fc..3c781f8e3287 100644 --- a/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java +++ b/python/src/com/jetbrains/python/documentation/PyDocstringGenerator.java @@ -51,6 +51,7 @@ public class PyDocstringGenerator { private final Map> myParamTypesOffset = Maps.newHashMap(); private PsiFile myFile; + private boolean myGenerateReturn; public PyDocstringGenerator(@NotNull PyDocStringOwner docStringOwner) { myDocStringOwner = docStringOwner; @@ -94,6 +95,10 @@ public class PyDocstringGenerator { return this; } + public void withReturn() { + myGenerateReturn = true; + } + private PsiFile getFile() { return myFile; } @@ -261,6 +266,14 @@ public class PyDocstringGenerator { } } + if (myGenerateReturn && myDocStringOwner instanceof PyFunction) { + PyFunction function = (PyFunction)myDocStringOwner; + String returnType = PythonDocumentationProvider.generateRaiseOrReturn(function, " ", getPrefix(), true); + if (!returnType.isEmpty()) { + replacementText.append(ws).append(returnType); + } + } + int offset = replacementText.length(); if (addWS) { replacementText.append(ws); diff --git a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java index cae14be634d9..d691fcc80fd0 100644 --- a/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java +++ b/python/src/com/jetbrains/python/documentation/PythonDocumentationProvider.java @@ -567,6 +567,12 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i builder.append(offset); } } + builder.append(generateRaiseOrReturn(element, offset, prefix, checkReturn)); + return builder.toString(); + } + + public static String generateRaiseOrReturn(PyFunction element, String offset, String prefix, boolean checkReturn) { + StringBuilder builder = new StringBuilder(); if (checkReturn) { RaiseVisitor visitor = new RaiseVisitor(); PyStatementList statementList = element.getStatementList(); diff --git a/python/testData/intentions/afterTypeInDocstring.py b/python/testData/intentions/afterTypeInDocstring.py index 910a0afdb11f..fa2dab51d1b3 100644 --- a/python/testData/intentions/afterTypeInDocstring.py +++ b/python/testData/intentions/afterTypeInDocstring.py @@ -1,5 +1,6 @@ def foo(a, b): """ + :type a: object """ a. diff --git a/python/testData/intentions/afterTypeInDocstring1.py b/python/testData/intentions/afterTypeInDocstring1.py index 3422432d15c7..1eb6510bc70f 100644 --- a/python/testData/intentions/afterTypeInDocstring1.py +++ b/python/testData/intentions/afterTypeInDocstring1.py @@ -1,5 +1,6 @@ def foo(a, b): """ + :rtype : object """ b = 1 \ No newline at end of file diff --git a/python/testData/intentions/afterTypeInDocstring2.py b/python/testData/intentions/afterTypeInDocstring2.py index d38dfb10211b..cc1fe71acf10 100644 --- a/python/testData/intentions/afterTypeInDocstring2.py +++ b/python/testData/intentions/afterTypeInDocstring2.py @@ -1,5 +1,6 @@ def func1(x): """ + :rtype : object """ return x diff --git a/python/testData/intentions/afterTypeInDocstring3.py b/python/testData/intentions/afterTypeInDocstring3.py index 009561da2dca..508df1bf9e0f 100644 --- a/python/testData/intentions/afterTypeInDocstring3.py +++ b/python/testData/intentions/afterTypeInDocstring3.py @@ -1,5 +1,6 @@ def foo3(x, y, z, aa): #comment """ + :type y: object """ i = xx + y + z diff --git a/python/testData/intentions/afterTypeInDocstring4.py b/python/testData/intentions/afterTypeInDocstring4.py index 56fc78a28593..833eb614bfe5 100644 --- a/python/testData/intentions/afterTypeInDocstring4.py +++ b/python/testData/intentions/afterTypeInDocstring4.py @@ -2,5 +2,6 @@ class ProjectElement(object): def __init__(self, project_name='', info_source='', project_id=None, has_revisions=True): """ + :type project_name: object """ \ No newline at end of file diff --git a/python/testData/intentions/afterTypeInDocstring5.py b/python/testData/intentions/afterTypeInDocstring5.py index 8ef60a61ec1a..d8bb2c5e2f1c 100644 --- a/python/testData/intentions/afterTypeInDocstring5.py +++ b/python/testData/intentions/afterTypeInDocstring5.py @@ -1,5 +1,6 @@ def foo3(param): """ + :type param: object """ i = param.unresolved() \ No newline at end of file From 07862a55267340fac8812d0b8891af9e5e7129c3 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Mon, 11 Feb 2013 23:57:09 +0400 Subject: [PATCH 53/54] RUBY-13071: (refactoring) RegExpPropertiesProvider iface merged into RegExpLanguageHost --- .../impl/PyStringLiteralExpressionImpl.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java index 3453fc3ac67e..525fa2b70a5a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyStringLiteralExpressionImpl.java @@ -17,9 +17,11 @@ import com.jetbrains.python.lexer.PythonHighlightingLexer; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; +import org.intellij.lang.regexp.DefaultRegExpPropertiesProvider; import org.intellij.lang.regexp.RegExpLanguageHost; import org.intellij.lang.regexp.psi.RegExpGroup; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.regex.Matcher; @@ -32,6 +34,7 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt private static final Map escapeMap = initializeEscapeMap(); private String stringValue; private List valueTextRanges; + private final DefaultRegExpPropertiesProvider myPropertiesProvider; private static Map initializeEscapeMap() { Map map = new HashMap(); @@ -51,6 +54,7 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt public PyStringLiteralExpressionImpl(ASTNode astNode) { super(astNode); + myPropertiesProvider = DefaultRegExpPropertiesProvider.getInstance(); } @Override @@ -431,4 +435,27 @@ public class PyStringLiteralExpressionImpl extends PyElementImpl implements PySt public boolean supportsNamedGroupSyntax(RegExpGroup group) { return group.isPythonNamedGroup(); } + + @Override + public boolean isValidCategory(@NotNull String category) { + return myPropertiesProvider.isValidCategory(category); + } + + @NotNull + @Override + public String[][] getAllKnownProperties() { + return myPropertiesProvider.getAllKnownProperties(); + } + + @Nullable + @Override + public String getPropertyDescription(@Nullable String name) { + return myPropertiesProvider.getPropertyDescription(name); + } + + @NotNull + @Override + public String[][] getKnownCharacterClasses() { + return myPropertiesProvider.getKnownCharacterClasses(); + } } From 0f4a97b4080b6f090e246cf1a0c66bde3ae2f044 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 12 Feb 2013 14:58:05 +0100 Subject: [PATCH 54/54] new python file type --- .../icons/com/jetbrains/python/pythonFile.png | Bin 418 -> 603 bytes .../com/jetbrains/python/pythonFile@2x.png | Bin 997 -> 1109 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/python/psi-api/resources/icons/com/jetbrains/python/pythonFile.png b/python/psi-api/resources/icons/com/jetbrains/python/pythonFile.png index 43aa9ef5f7d5a33d8eedeae04b0614abef68053d..6d284ad8f77f0327f6e86e96c170254943f74bc1 100644 GIT binary patch delta 541 zcmV+&0^a ziw6&S%~9~8g0zUX2eIHEAVR>Sc_Nms;!NsG0kRvtZ&n#mN1t3 z;A3ar&V1kZ-WwLjF(gqe7Izo_j;Dl)&ZbZ(w7wh;A9n~(x_^_xa*$baiMu>uw!PnT z@;?q%3Fq3S9OwWJaCMikbtr<@OCl|Vm_fmFbiXgjxlDb!eli*loWJL+CFJ{F019!z z5B$roMkm8;Zw7jgW&zVj23LM#ko+&d8?q8aFBjtM?U{#H0r^18+4Q}SQ*S}wSM*%K zlncJtE_%MWA;W87C5p|ib*f;sQEM){G=iAnG-G-@l}XLo9IRzi@ME;! z%!k2dwL?(*zSaM}HkPk%Y~P@UtfRm;)Wr2}2W&}^T#eM@_(=z0E{Y-#%Tv%a_;{2mx+ag>7N=%{M&!= zK1PQBPgxkh|662b`1~CxbPt~kH0{N|ZwCbw6XV|!kN_9s%cB1bjMqRBk#J*`6EGk# zVgVzmI#piensQ>@~07*qoM6N<$f}7%= Awg3PC diff --git a/python/psi-api/resources/icons/com/jetbrains/python/pythonFile@2x.png b/python/psi-api/resources/icons/com/jetbrains/python/pythonFile@2x.png index efddd109f10419627e117f2d61b36970208fcda5..cbfcdf9b4030a12f0c6fe1dedd4fbf33f2ee21a0 100644 GIT binary patch delta 1051 zcmV+$1myeW2h|9WNq_fAL_t(|+Qe5)XkA4Vp1=E(o0q1MrdkM8st9VJ4N9vEiGolu zpc_GO;i5t6Mo_BKqT<37v`BFyVl`@3R>YzUvr!^Jq@o)|Og7S0O>wkNZ z@JiLeTS36oA+Z$%o~%PcRhW?1Sh;Oy2%7LtL4s|jiLLN}ZSPsV5uhM3v)vl7c%LAP zz8ALJ1C^WV<6OLlCbm5b{x=VFx2FlCggXi`_Lsoi&-^*1ttb zh6A=hT@!sJFn_ls9*c&eQ(@>Y2_ZfZf*;|6k8a#YG(i%l6N{@&c<4rbn!5J&RRcj7 z9F7JG~V>v2Y-C7>GjF7>XEp(E%FXBCPe5fbyggQZN8~C&=FU8Hnb;&O+_&d-*LPt) zzwUc*xjKP2zfT0M_y`%em)z}#5wbYR7{xv}q-oU*jHKB(Z%b0=J3;I2(YK!>Wj;>7 z|Dmo$8grC>|5}*<89fyY1jjtjW7hQ+_8>#vE>w@!vO}2wf*Y_dFy3v1yWJqCOd-G= z_1|BaKz}e09*r6i#a>;rHgea=t@=AQKmbQECKrYIK<;=#hLg24pnR_(t#QFOsXp|L zro0(2gYe4^f0bO7?q|Gh%79U|2-s<@vMJ2fOCn%%Cr?j|H$FTmg%~M^rhE>qM!=>P z;8m>9;I}*E+PMQem&YX6!Ieq5hC|maxAp`p&wopfhn)Ai=Bq^j036CI01a=wd)Lgz zMrWVU+D5uPW*6)PtJF0XRMP`iTv&Ptv|fvwt!KD_?_{7xauIfghx1K5S~moMnXwyB zvHC1d&wup5=>#<&Z^xEb*GIlR*YE(q0)^nPHHH*Fon}cfmFOHtTG7zstYX}ULdU$o z`+vL+f#VO~#O4=Q^sW}jabge*dnWyA_1QZoM_+3jr->nR#xF7{f65Duu}xwIJ|(41 zVw9dduLAGoIt2FL&=B7|dJCSU=Ue&S?%C^l`K^x51q8J5bu75uDGe&r7${$TDt-0F ze=SDV%8Ijc~$Cc!4%d1ZC3o2DpWiL>CS+<@I-ZS#*8J%PY?dp{; zzwCLG?tVS5+AhrBY9+Qi`78b`T~7{P@uq2?$hnlwU?@E6NB$Gt8^y+X;9mg-02InC Vz1IGX0Z0G<002ovPDHLkV1m0Z250~P delta 938 zcmV;b16BOh2;~QmNq>h)L_t(|+U!?Lh!sZ^tzUoMdozf?NpxZabrDffK@b%JNyx&u z5JW)`R5BYyH*pn+?i5iJR20NvLfmDSgrJZ`#HB`%D1J~w2#6?7#1Avhba&mlp6Yo$ z&eNG>`Z>>qc;V31)%B{*J@?kFdXkyNNbBk8Y3wL(`+(hJeShrg>S}mbV&d&PVDESb zw}JqdA<+r~+scqIQVuOg8{kNA)=hhGiqhMZKiG);Y8rD@N z3*==@-xavfj*#k-q`NEby!lXNkFn{D^SlB6Z;;nf70Qd{|xqeWU zC!me#j^c2O(i+Z5q4BiVq0J5Tw;+T(@PIIUL<%{HF#^w%__V#L5QLRzL)=ysm9~nA zY87GP5P{dZ)E>@zjYTs{!@%l&Y}w@3PnLqL+uU>rOrWbe(4vrdG;_`kw~2^Xbl$lK z4Qi_X8-KR0+B5;i+>W^Muw#+pc6}N0_7&Y#%^m0)SkV69{HDcc*ZaegY3QTNT=PkY zaC)y^dQ0y1_Qk&(__XutTD(p!`V(70hH$&lgWqVSLw0zpv$GjBPXG(%DB54nx^Q?^ z$DgIWm4D0)s%Ddw-H<*_Qdg&qi`#aW(qgj9#yRl)0=7 zfsr#D{4jRc9uY0`NyygP-e)tHPOIG&&b%B(sTHsO<0@wI)e*Y<)~o{a*34BuUA&*( zd77%J#?T{3GRdJ16rS3|ij1pgut=|x&PwUG1hJ&dfb%o--&27;-YkK2S_!+dQ{IO! z|9{};&xNzg38hZgW9$o*PW!)rqglRb2-&BCqe|*MJRC-TqqATRun71BNF{2o_ufmJ zBTqPv+39mE)E@{%JCp4!b03gp4kJgjGaI0_L4=iy`k#<6p}fUbbkHE$vA#OyReIE9 z8K?PE4aqN){^ZBBZ*U!^YH$dAY*>qajU#ID27IFi8Na%jKVJwi07TBCP{rH%%K!iX M07*qoM6N<$g42iFOaK4?