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
|
# File 'lib/milk_tea/core/control_flow/definite_assignment.rb', line 9
def self.solve(graph, initially_assigned: Set.new)
initially_assigned = initially_assigned.dup
universe = initial_universe(graph, initially_assigned)
result = Dataflow.solve(
graph,
direction: :forward,
initial: -> { universe.dup },
join: lambda do |states|
if states.empty?
universe.dup
else
states.reduce(universe.dup) { |acc, state| acc & state }
end
end,
transfer: lambda do |node, in_state|
in_state | node.writes
end,
boundary_in: { graph.entry_id => initially_assigned.dup }
)
read_before_assignment = []
graph.each_node do |node|
in_state = result.in_states[node.id]
if node.reads_info.empty?
node.reads.each do |binding_key|
next if in_state.include?(binding_key)
read_before_assignment << ReadBeforeAssignment.new(
node_id: node.id,
binding_key:,
line: node.line,
column: nil,
length: nil,
)
end
next
end
node.reads_info.each do |read_site|
next if in_state.include?(read_site.binding_key)
read_before_assignment << ReadBeforeAssignment.new(
node_id: node.id,
binding_key: read_site.binding_key,
line: read_site.line || node.line,
column: read_site.column,
length: read_site.length,
)
end
end
Result.new(
definitely_assigned_in: result.in_states,
definitely_assigned_out: result.out_states,
read_before_assignment:
)
end
|