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:
@@ -305,27 +305,4 @@ public class PyImportReferenceImpl extends PyReferenceImpl {
|
||||
editor.getCaretModel().moveToOffset(tailOffset + IMPORT_KWD.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
PyImportReferenceImpl that = (PyImportReferenceImpl)o;
|
||||
|
||||
if (!myElement.equals(that.myElement)) return false;
|
||||
if (!myContext.equals(that.myContext)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + myElement.hashCode();
|
||||
result = 31 * result + myContext.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,19 +20,19 @@ public class PyABCUtil {
|
||||
}
|
||||
|
||||
public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName) {
|
||||
final String subClassName = subClass.getName();
|
||||
if (PyNames.CALLABLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.CALL);
|
||||
}
|
||||
if (PyNames.HASHABLE.equals(superClassName)) {
|
||||
return hasMethod(subClass, PyNames.HASH);
|
||||
}
|
||||
final boolean isIterable = hasMethod(subClass, PyNames.ITER);
|
||||
final boolean hasIter = hasMethod(subClass, PyNames.ITER);
|
||||
final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM);
|
||||
if (PyNames.ITERABLE.equals(superClassName)) {
|
||||
return isIterable || isStringClass(subClassName);
|
||||
return hasIter || hasGetItem;
|
||||
}
|
||||
if (PyNames.ITERATOR.equals(superClassName)) {
|
||||
return (isIterable && hasMethod(subClass, PyNames.NEXT)) || isStringClass(subClassName);
|
||||
return (hasIter && hasMethod(subClass, PyNames.NEXT)) || hasGetItem;
|
||||
}
|
||||
final boolean isSized = hasMethod(subClass, PyNames.LEN);
|
||||
if (PyNames.SIZED.equals(superClassName)) {
|
||||
@@ -42,12 +42,11 @@ public class PyABCUtil {
|
||||
if (PyNames.CONTAINER.equals(superClassName)) {
|
||||
return isContainer;
|
||||
}
|
||||
final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM);
|
||||
if (PyNames.SEQUENCE.equals(superClassName)) {
|
||||
return isSized && isIterable && isContainer && hasGetItem;
|
||||
return isSized && hasIter && isContainer && hasGetItem;
|
||||
}
|
||||
if (PyNames.MAPPING.equals(superClassName)) {
|
||||
return isSized && isIterable && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS);
|
||||
return isSized && hasIter && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -74,8 +73,4 @@ public class PyABCUtil {
|
||||
private static boolean hasMethod(PyClass cls, String name) {
|
||||
return cls.findMethodByName(name, true) != null;
|
||||
}
|
||||
|
||||
private static boolean isStringClass(String className) {
|
||||
return "bytes".equals(className) || "str".equals(className) || "unicode".equals(className);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,12 @@ public class TypeEvalContext {
|
||||
private final PsiFile myOrigin;
|
||||
|
||||
private final Map<PyTypedElement, PyType> myEvaluated = new HashMap<PyTypedElement, PyType>();
|
||||
private final Set<PyTypedElement> myEvaluating = new HashSet<PyTypedElement>();
|
||||
private final ThreadLocal<Set<PyTypedElement>> myEvaluating = new ThreadLocal<Set<PyTypedElement>>() {
|
||||
@Override
|
||||
protected Set<PyTypedElement> initialValue() {
|
||||
return new HashSet<PyTypedElement>();
|
||||
}
|
||||
};
|
||||
|
||||
private TypeEvalContext(boolean allowDataFlow, boolean allowStubToAST, PsiFile origin) {
|
||||
myAllowDataFlow = allowDataFlow;
|
||||
@@ -111,17 +116,22 @@ public class TypeEvalContext {
|
||||
if (myEvaluated.containsKey(element)) {
|
||||
return myEvaluated.get(element);
|
||||
}
|
||||
if (myEvaluating.contains(element)) {
|
||||
return null;
|
||||
}
|
||||
final Set<PyTypedElement> evaluating = myEvaluating.get();
|
||||
if (evaluating.contains(element)) {
|
||||
return null;
|
||||
}
|
||||
evaluating.add(element);
|
||||
try {
|
||||
PyType result = element.getType(this);
|
||||
synchronized (myEvaluated) {
|
||||
myEvaluated.put(element, result);
|
||||
}
|
||||
myEvaluating.add(element);
|
||||
return result;
|
||||
}
|
||||
PyType result = element.getType(this);
|
||||
synchronized (myEvaluated) {
|
||||
myEvaluating.remove(element);
|
||||
myEvaluated.put(element, result);
|
||||
finally {
|
||||
evaluating.remove(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean maySwitchToAST(StubBasedPsiElement element) {
|
||||
|
||||
@@ -8,4 +8,18 @@ def test_union_type():
|
||||
def foo(*args):
|
||||
pass
|
||||
bar = (1,) if True else (1, 2)
|
||||
foo(*bar) #pass
|
||||
foo(*bar) #pass
|
||||
|
||||
# PY-4890
|
||||
def test_old_style_iterable():
|
||||
class C:
|
||||
def __getitem__(self, key):
|
||||
if 0 <= key < 10:
|
||||
return key
|
||||
else:
|
||||
raise IndexError('index out of range')
|
||||
def foo(*args):
|
||||
pass
|
||||
xs = C()
|
||||
foo(*xs) #pass
|
||||
foo(*'bar') #pass
|
||||
Reference in New Issue
Block a user