Merge remote branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2011-08-09 19:57:54 +02:00
6 changed files with 82 additions and 20 deletions
@@ -3,6 +3,8 @@ package com.jetbrains.python.psi.types;
import com.jetbrains.python.psi.PyClass;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author vlan
*/
@@ -22,8 +24,14 @@ public class PyTypeChecker {
return match(expected, ((PyTypeReference)actual).resolve(null, context), context);
}
if (actual instanceof PyUnionType) {
for (PyType t : ((PyUnionType)actual).getMembers()) {
if (!match(expected, t, context)) {
final List<PyType> members = ((PyUnionType)actual).getMembers();
for (PyType m : members) {
if (m == null) {
return true;
}
}
for (PyType m : members) {
if (!match(expected, m, context)) {
return false;
}
}
@@ -237,9 +237,7 @@ public class PyTypeParser {
PyType result = null;
for (TextRange range : ranges) {
final PyType t = parse(anchor, range.substring(type), types, fullRanges, offset + range.getStartOffset());
if (t != null) {
result = (result == null) ? t : PyUnionType.union(result, t);
}
result = (result == null) ? t : PyUnionType.union(result, t);
}
return result;
}
@@ -33,21 +33,9 @@ public class PyDefUseUtil {
throw new InstructionNotFoundException();
}
final boolean[] visited = new boolean[instructions.length];
final Collection<PyElement> result = new HashSet<PyElement>();
final Collection<PyElement> result = new LinkedHashSet<PyElement>();
getLatestDefs(var, instructions, instr, visited, result);
final List<PyElement> sortedResult = new ArrayList<PyElement>();
sortedResult.addAll(result);
Collections.sort(sortedResult, new Comparator<PyElement>() {
@Override
public int compare(PyElement e1, PyElement e2) {
final String n1 = e1.getName();
if (n1 != null) {
return n1.compareTo(e2.getName());
}
return 0;
}
});
return sortedResult.toArray(new PyElement[sortedResult.size()]);
return result.toArray(new PyElement[result.size()]);
}
private static void getLatestDefs(final PyElement var,
@@ -220,4 +220,65 @@ def test_old_style_classes():
:type x: object
"""
pass
f(C()) #pass
f(C()) #pass
def test_partly_unknown_type():
def f():
"""
:rtype: None or unknown or int or long
"""
def g(x):
"""
:type x: object
"""
g(f())
def test_type_assertions():
def f_1():
"""
:rtype: int or str or None
"""
def f_2():
"""
:rtype: int or None
"""
def f_3():
"""
:rtype: unknown
"""
def f_4():
"""
:rtype: object
"""
def f_5():
"""
:rtype: int or object
"""
def f_6():
"""
:rtype: int or unknown or float
"""
def f_7():
"""
:rtype: int or unknown
"""
def print_int(x):
"""
:type x: int
"""
print(x)
def print_int_or_str(x):
"""
:type x: int or str
"""
x_1 = f_1()
print_int(<warning descr="Expected type 'int', got 'one of (int, str, None)' instead">x_1</warning>)
print_int_or_str(<warning descr="Expected type 'one of (int, str)', got 'one of (int, str, None)' instead">x_1</warning>)
if isinstance(x_1, int):
print_int(x_1)
if isinstance(x_1, str):
print_int_or_str(x_1)
x_7 = f_7()
print_int(x_7)
+1
View File
@@ -0,0 +1 @@
<html><body><small>Assigned to <code>y</code><br></small><code><br>Inferred&nbsp;type:&nbsp;one&nbsp;of&nbsp;(str,&nbsp;int)</code></body></html>
+6
View File
@@ -0,0 +1,6 @@
def f(x):
if x:
y = 1
else:
y = 'foo'
return <the_ref>y