mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -677,6 +677,9 @@ __builtin__.str.find = \
|
||||
:type end: int or long or None \n\
|
||||
:rtype: int \n\
|
||||
|
||||
__builtin__.str.format = \
|
||||
:rtype: bytes \n\
|
||||
|
||||
__builtin__.str.index = \
|
||||
:type sub: string \n\
|
||||
:type start: int or long or None \n\
|
||||
@@ -817,10 +820,14 @@ __builtin__.unicode.__rmul__ = \
|
||||
__builtin__.unicode.__rmod__ = \
|
||||
:type y: object \n\
|
||||
:rtype: unicode \n\
|
||||
|
||||
__builtin__.unicode.__getitem__ = \
|
||||
:type y: int \n\
|
||||
:rtype: unicode \n\
|
||||
|
||||
__builtin__.unicode.format = \
|
||||
:rtype: unicode \n\
|
||||
|
||||
__builtin__.unicode.capitalize = \
|
||||
:rtype: unicode \n\
|
||||
|
||||
|
||||
@@ -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.121" # Must be a number-dot-number string, updated with each change that affects generated skeletons
|
||||
VERSION = "1.122" # Must be a number-dot-number string, updated with each change that affects generated skeletons
|
||||
# Note: DON'T FORGET TO UPDATE!
|
||||
|
||||
import sys
|
||||
@@ -817,9 +817,15 @@ class ModuleRedeclarator(object):
|
||||
PREDEFINED_BUILTIN_SIGS[(None, "max")] = "(*args, key=None)"
|
||||
PREDEFINED_BUILTIN_SIGS[(None, "open")] = "(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)"
|
||||
PREDEFINED_BUILTIN_SIGS[("str", "__init__")] = "(self, value='', encoding=None, errors='strict')" # overrides a fake
|
||||
PREDEFINED_BUILTIN_SIGS[("str", "format")] = "(*args, **kwargs)"
|
||||
PREDEFINED_BUILTIN_SIGS[("bytes", "__init__")] = "(self, value=b'', encoding=None, errors='strict')" # overrides a fake
|
||||
PREDEFINED_BUILTIN_SIGS[("bytes", "format")] = "(*args, **kwargs)"
|
||||
PREDEFINED_BUILTIN_SIGS[(None, "print")] = "(*args, sep=' ', end='\\n', file=None)" # proper signature
|
||||
|
||||
if version >= (2, 6) and version < (3, 0):
|
||||
PREDEFINED_BUILTIN_SIGS[("unicode", "format")] = "(*args, **kwargs)"
|
||||
PREDEFINED_BUILTIN_SIGS[("str", "format")] = "(*args, **kwargs)"
|
||||
|
||||
if version == (2, 5):
|
||||
PREDEFINED_BUILTIN_SIGS[("unicode", "splitlines")] = "(keepends=None)" # a typo in docstring there
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
(default) 1.92 # anything not explicitly marked
|
||||
|
||||
(built-in) 1.119 # skeletons of all built-in modules are built together
|
||||
(built-in) 1.122 # 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
|
||||
|
||||
@@ -136,11 +136,11 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
|
||||
/**
|
||||
* Non-recursively searches for a property for which the given function is a getter, setter or deleter.
|
||||
*
|
||||
* @param function the function which may be an accessor
|
||||
* @param callable the function which may be an accessor
|
||||
* @return the property, or null
|
||||
*/
|
||||
@Nullable
|
||||
Property findPropertyByFunction(PyFunction function);
|
||||
Property findPropertyByCallable(Callable callable);
|
||||
|
||||
/**
|
||||
* @param parent
|
||||
|
||||
@@ -688,7 +688,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
|
||||
super.visitPyAssertStatement(node);
|
||||
final PyExpression[] args = node.getArguments();
|
||||
// assert False
|
||||
if (args.length == 1 && PyConstantExpressionEvaluator.evaluate(args[0]) == Boolean.FALSE) {
|
||||
if (args.length >= 1 && PyConstantExpressionEvaluator.evaluate(args[0]) == Boolean.FALSE) {
|
||||
abruptFlow(node);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -662,14 +662,14 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public Property findPropertyByFunction(PyFunction function) {
|
||||
public Property findPropertyByCallable(Callable callable) {
|
||||
if (myPropertyCache == null) {
|
||||
myPropertyCache = initializePropertyCache();
|
||||
}
|
||||
for (Property property : myPropertyCache.values()) {
|
||||
if (property.getGetter().valueOrNull() == function ||
|
||||
property.getSetter().valueOrNull() == function ||
|
||||
property.getDeleter().valueOrNull() == function) {
|
||||
if (property.getGetter().valueOrNull() == callable ||
|
||||
property.getSetter().valueOrNull() == callable ||
|
||||
property.getDeleter().valueOrNull() == callable) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
|
||||
public Property getProperty() {
|
||||
final PyClass containingClass = getContainingClass();
|
||||
if (containingClass != null) {
|
||||
return containingClass.findPropertyByFunction(this);
|
||||
return containingClass.findPropertyByCallable(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,10 +8,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.stubs.StubUpdatingIndex;
|
||||
@@ -376,17 +373,6 @@ public class PyQualifiedReference extends PyReferenceImpl {
|
||||
if (isLocalScope(element)) {
|
||||
return false;
|
||||
}
|
||||
PsiElement resolveResult = resolve();
|
||||
if (resolveResult instanceof PyImportedModule) {
|
||||
resolveResult = resolveResult.getNavigationElement();
|
||||
}
|
||||
if (element instanceof PsiDirectory && resolveResult instanceof PyFile &&
|
||||
PyNames.INIT_DOT_PY.equals(((PyFile)resolveResult).getName()) && ((PyFile)resolveResult).getContainingDirectory() == element) {
|
||||
return true;
|
||||
}
|
||||
if (resolveResult == element) {
|
||||
return true;
|
||||
}
|
||||
final String referencedName = myElement.getReferencedName();
|
||||
if (element instanceof PyFunction && Comparing.equal(referencedName, ((PyFunction)element).getName()) &&
|
||||
((PyFunction)element).getContainingClass() != null && !PyNames.INIT.equals(referencedName)) {
|
||||
@@ -399,6 +385,30 @@ public class PyQualifiedReference extends PyReferenceImpl {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ResolveResult result : multiResolve(false)) {
|
||||
if (result instanceof ImplicitResolveResult) {
|
||||
continue;
|
||||
}
|
||||
PsiElement resolveResult = result.getElement();
|
||||
if (isResolvedToResult(element, resolveResult)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isResolvedToResult(PsiElement element, PsiElement resolveResult) {
|
||||
if (resolveResult instanceof PyImportedModule) {
|
||||
resolveResult = resolveResult.getNavigationElement();
|
||||
}
|
||||
if (element instanceof PsiDirectory && resolveResult instanceof PyFile &&
|
||||
PyNames.INIT_DOT_PY.equals(((PyFile)resolveResult).getName()) && ((PyFile)resolveResult).getContainingDirectory() == element) {
|
||||
return true;
|
||||
}
|
||||
if (resolveResult == element) {
|
||||
return true;
|
||||
}
|
||||
if (resolveResult instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)resolveResult) &&
|
||||
element instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)element) && Comparing.equal(
|
||||
((PyTargetExpression)resolveResult).getReferencedName(),
|
||||
@@ -415,7 +425,6 @@ public class PyQualifiedReference extends PyReferenceImpl {
|
||||
if (resolvesToWrapper(element, resolveResult)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package com.jetbrains.python.refactoring.rename;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Processor;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.psi.Callable;
|
||||
import com.jetbrains.python.psi.Property;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.search.PyOverridingMethodsSearch;
|
||||
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
|
||||
import com.jetbrains.python.toolbox.Maybe;
|
||||
@@ -78,6 +76,24 @@ public class RenamePyFunctionProcessor extends RenamePyElementProcessor {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
final Property property = containingClass.findPropertyByCallable(function);
|
||||
final PyTargetExpression site;
|
||||
if (property != null) {
|
||||
site = property.getDefinitionSite();
|
||||
if (site != null) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return site;
|
||||
}
|
||||
final String message = String.format("Do you want to rename the property '%s' instead of its accessor function '%s'?",
|
||||
property.getName(), function.getName());
|
||||
final int rc = Messages.showYesNoCancelDialog(element.getProject(), message, "Rename", Messages.getQuestionIcon());
|
||||
switch (rc) {
|
||||
case 0: return site;
|
||||
case 1: return function;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
@@ -93,7 +109,7 @@ public class RenamePyFunctionProcessor extends RenamePyElementProcessor {
|
||||
});
|
||||
final PyClass containingClass = function.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final Property property = containingClass.findPropertyByFunction(function);
|
||||
final Property property = containingClass.findPropertyByCallable(function);
|
||||
if (property != null) {
|
||||
addRename(allRenames, newName, property.getGetter());
|
||||
addRename(allRenames, newName, property.getSetter());
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.jetbrains.python.refactoring.rename;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -35,4 +38,25 @@ public class RenamePyVariableProcessor extends RenamePyElementProcessor {
|
||||
public void setToSearchForTextOccurrences(PsiElement element, boolean enabled) {
|
||||
PyCodeInsightSettings.getInstance().RENAME_SEARCH_NON_CODE_FOR_VARIABLE = enabled;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement substituteElementToRename(PsiElement element, @Nullable Editor editor) {
|
||||
if (element instanceof PyLambdaExpression) {
|
||||
final PyLambdaExpression lambdaExpression = (PyLambdaExpression)element;
|
||||
final ScopeOwner owner = ScopeUtil.getScopeOwner(lambdaExpression);
|
||||
if (owner instanceof PyClass) {
|
||||
final PyClass cls = (PyClass)owner;
|
||||
final Property property = cls.findPropertyByCallable(lambdaExpression);
|
||||
if (property != null) {
|
||||
final PyTargetExpression site = property.getDefinitionSite();
|
||||
if (site != null) {
|
||||
return site;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
assert False, 'foo'
|
||||
print('unreachable 1')
|
||||
assert False, f()
|
||||
print('unreachable 2')
|
||||
@@ -0,0 +1,7 @@
|
||||
0(1) element: null
|
||||
1(6) READ ACCESS: False
|
||||
2(3) element: PyPrintStatement
|
||||
3(4) READ ACCESS: False
|
||||
4(6) READ ACCESS: f
|
||||
5(6) element: PyPrintStatement
|
||||
6() element: null
|
||||
@@ -0,0 +1,18 @@
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._foo = 'foo'
|
||||
|
||||
def get_foo(self):
|
||||
return self._foo
|
||||
|
||||
def set_foo(self, value):
|
||||
self._foo = value
|
||||
|
||||
def __str__(self):
|
||||
return self.foo
|
||||
|
||||
foo = property(get_foo, set_foo)
|
||||
|
||||
|
||||
c = C()
|
||||
print(c.f<caret>oo)
|
||||
@@ -0,0 +1,18 @@
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._foo = 'foo'
|
||||
|
||||
def get_foo(self):
|
||||
return self._foo
|
||||
|
||||
def set_foo(self, value):
|
||||
self._foo = value
|
||||
|
||||
def __str__(self):
|
||||
return self.bar
|
||||
|
||||
bar = property(get_foo, set_foo)
|
||||
|
||||
|
||||
c = C()
|
||||
print(c.bar)
|
||||
@@ -0,0 +1,5 @@
|
||||
class C(object):
|
||||
foo = property(lambda self: 'bar')
|
||||
|
||||
c = C()
|
||||
print(c.f<caret>oo, c.foo)
|
||||
@@ -0,0 +1,5 @@
|
||||
class C(object):
|
||||
bar = property(lambda self: 'bar')
|
||||
|
||||
c = C()
|
||||
print(c.bar, c.bar)
|
||||
@@ -215,6 +215,11 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
|
||||
doTestFirstStatement();
|
||||
}
|
||||
|
||||
// PY-7784
|
||||
public void testAssertFalseArgument() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTestFirstStatement() {
|
||||
final String testName = getTestName(false).toLowerCase();
|
||||
configureByFile(testName + ".py");
|
||||
|
||||
@@ -137,6 +137,16 @@ public class PyRenameTest extends PyTestCase {
|
||||
doRenameConflictTest("foo", "A variable named 'foo' is already defined in variableNameConflict.py");
|
||||
}
|
||||
|
||||
// PY-8315
|
||||
public void testRenamePropertyWithLambda() {
|
||||
doTest("bar");
|
||||
}
|
||||
|
||||
// PY-8315
|
||||
public void testRenameOldStyleProperty() {
|
||||
doTest("bar");
|
||||
}
|
||||
|
||||
private void doRenameConflictTest(String newName, String expectedConflict) {
|
||||
myFixture.configureByFile("refactoring/rename/" + getTestName(true) + ".py");
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user