| 1 | module transform |
| 2 | |
| 3 | import v3.flat |
| 4 | |
| 5 | // match_has_sum_type_subject checks if a match_stmt's subject expression |
| 6 | // resolves to a sum type. This determines whether the match needs to be |
| 7 | // lowered with is_expr conditions (sum type dispatch) or plain equality |
| 8 | // checks (value matching). |
| 9 | fn (mut t Transformer) match_has_sum_type_subject(node flat.Node) bool { |
| 10 | if node.children_count == 0 { |
| 11 | return false |
| 12 | } |
| 13 | subject_id := t.a.child(&node, 0) |
| 14 | subject_type := t.resolve_expr_type(subject_id) |
| 15 | if subject_type.len == 0 { |
| 16 | return false |
| 17 | } |
| 18 | return subject_type in t.sum_types |
| 19 | } |
| 20 | |
| 21 | // resolve_match_subject_type determines the type of a match subject expression. |
| 22 | // Uses resolve_expr_type on child 0 (the match expression). |
| 23 | fn (mut t Transformer) resolve_match_subject_type(node flat.Node) string { |
| 24 | if node.children_count == 0 { |
| 25 | return '' |
| 26 | } |
| 27 | subject_id := t.a.child(&node, 0) |
| 28 | return t.resolve_expr_type(subject_id) |
| 29 | } |
| 30 | |
| 31 | // transform_match_branch_body transforms a match branch body with smartcast |
| 32 | // awareness. When the branch matches a sum type variant, the subject variable |
| 33 | // should be narrowed to that variant's type within the branch body. |
| 34 | // |
| 35 | // For now, this performs basic body transformation without smartcast injection. |
| 36 | // When smartcast support is fully wired up, this will: |
| 37 | // 1. Push a smartcast context for the subject variable narrowed to the variant |
| 38 | // 2. Transform the body statements under that context |
| 39 | // 3. Pop the smartcast context |
| 40 | // 4. Rebuild the block with the transformed statements |
| 41 | fn (mut t Transformer) transform_match_branch_body(branch_id flat.NodeId, subject_name string, variant_name string) flat.NodeId { |
| 42 | if int(branch_id) < 0 { |
| 43 | return branch_id |
| 44 | } |
| 45 | branch := t.a.nodes[int(branch_id)] |
| 46 | if branch.children_count == 0 { |
| 47 | return branch_id |
| 48 | } |
| 49 | // Collect the body statement ids from the branch |
| 50 | mut body_ids := []flat.NodeId{} |
| 51 | // Determine where the body starts (after the condition values) |
| 52 | n_conds := t.count_conds(branch) |
| 53 | for i in n_conds .. branch.children_count { |
| 54 | body_ids << t.a.child(&branch, i) |
| 55 | } |
| 56 | if body_ids.len == 0 { |
| 57 | return branch_id |
| 58 | } |
| 59 | // Push smartcast if we have a sum type variant match |
| 60 | mut has_sc := subject_name.len > 0 && variant_name.len > 0 |
| 61 | if has_sc { |
| 62 | sum_type_name := t.find_sum_type_for_variant(variant_name) |
| 63 | if sum_type_name.len > 0 { |
| 64 | t.push_smartcast(subject_name, variant_name, sum_type_name) |
| 65 | } else { |
| 66 | has_sc = false |
| 67 | } |
| 68 | } |
| 69 | // Transform the body statements under smartcast context |
| 70 | new_body := t.transform_stmts(body_ids) |
| 71 | if has_sc { |
| 72 | t.pop_smartcast() |
| 73 | } |
| 74 | return t.make_block(new_body) |
| 75 | } |
| 76 | |