-
Notifications
You must be signed in to change notification settings - Fork 0
/
solve.py
68 lines (57 loc) · 2.06 KB
/
solve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from mtypes import Typ, Void, NoneTyp, Any, ErrorType
from constraints import Constraint, SUPERTYPE_OF
import checker
from join import join_types
from meet import meet_types
from subtypes import is_subtype
def solve_constraints( vars, constraints, basic):
"""Solve type constraints.
Return lower bound for each type variable or None if the variable could
not be solved.
"""
# Collect a list of constraints for each type variable.
cmap = {}
for con in constraints:
a = cmap.get(con.type_var, [])
a.append(con)
cmap[con.type_var] = a
res = []
# Solve each type variable separately.
for tvar in vars:
bottom = None
top = None
# Process each contraint separely, and calculate the lower and upper
# bounds based on constraints. Note that we assume that the contraint
# targets do not have contraint references.
for c in cmap.get(tvar, []):
if c.op == SUPERTYPE_OF:
if bottom is None:
bottom = c.target
else:
bottom = join_types(bottom, c.target, basic)
else:
if top is None:
top = c.target
else:
top = meet_types(top, c.target, basic)
if top is None:
if isinstance(bottom, Void):
top = Void()
else:
top = basic.object
if bottom is None:
if isinstance(top, Void):
bottom = Void()
else:
bottom = NoneTyp()
if isinstance(top, Any) or isinstance(bottom, Any):
top = Any()
bottom = Any()
# Pick the most specific type if it satisfies the constraints.
if (not top or not bottom or is_subtype(bottom, top)) and (
not isinstance(top, ErrorType) and
not isinstance(bottom, ErrorType)):
res.append(bottom)
else:
res.append(None)
return res