| 1 | module transform |
| 2 | |
| 3 | import v3.flat |
| 4 | |
| 5 | // trim_pointer_type transforms trim pointer type data for transform. |
| 6 | fn (t &Transformer) trim_pointer_type(typ string) string { |
| 7 | if typ.starts_with('&') { |
| 8 | return typ[1..] |
| 9 | } |
| 10 | return typ |
| 11 | } |
| 12 | |
| 13 | // resolve_variant resolves resolve variant information for transform. |
| 14 | fn (t &Transformer) resolve_variant(sum_name string, variant string) string { |
| 15 | if variant.contains('.') { |
| 16 | return variant |
| 17 | } |
| 18 | resolved_sum := t.resolve_sum_name(sum_name) |
| 19 | if resolved_variant := t.sum_variant_name(resolved_sum, variant) { |
| 20 | return resolved_variant |
| 21 | } |
| 22 | if resolved_sum.contains('.') { |
| 23 | return '${resolved_sum.all_before_last('.')}.${variant}' |
| 24 | } |
| 25 | if sum_name.contains('.') { |
| 26 | return '${sum_name.all_before_last('.')}.${variant}' |
| 27 | } |
| 28 | return variant |
| 29 | } |
| 30 | |
| 31 | // resolve_sum_name resolves resolve sum name information for transform. |
| 32 | fn (t &Transformer) resolve_sum_name(sum_name string) string { |
| 33 | if sum_name.len == 0 { |
| 34 | return sum_name |
| 35 | } |
| 36 | if isnil(t.sum_cache) { |
| 37 | return t.resolve_sum_name_uncached(sum_name) |
| 38 | } |
| 39 | mut c := t.sum_cache |
| 40 | if c.module != t.cur_module { |
| 41 | c.module = t.cur_module |
| 42 | c.entries.clear() |
| 43 | } |
| 44 | if cached := c.entries[sum_name] { |
| 45 | return cached |
| 46 | } |
| 47 | result := t.resolve_sum_name_uncached(sum_name) |
| 48 | c.entries[sum_name] = result |
| 49 | return result |
| 50 | } |
| 51 | |
| 52 | // resolve_sum_name_uncached resolves resolve sum name uncached information for transform. |
| 53 | fn (t &Transformer) resolve_sum_name_uncached(sum_name string) string { |
| 54 | if sum_name in t.sum_types { |
| 55 | return sum_name |
| 56 | } |
| 57 | if sum_name.contains('.') { |
| 58 | short_sum := sum_name.all_after_last('.') |
| 59 | if short_sum in t.sum_types { |
| 60 | return short_sum |
| 61 | } |
| 62 | } |
| 63 | if !sum_name.contains('.') && t.cur_module.len > 0 && t.cur_module != 'main' |
| 64 | && t.cur_module != 'builtin' { |
| 65 | qsum := '${t.cur_module}.${sum_name}' |
| 66 | if qsum in t.sum_types { |
| 67 | return qsum |
| 68 | } |
| 69 | } |
| 70 | if !sum_name.contains('.') { |
| 71 | mut found := '' |
| 72 | for key, _ in t.sum_types { |
| 73 | if key.contains('.') && key.all_after_last('.') == sum_name { |
| 74 | if found.len > 0 && found != key { |
| 75 | found = '' |
| 76 | break |
| 77 | } |
| 78 | found = key |
| 79 | } |
| 80 | } |
| 81 | if found.len > 0 { |
| 82 | return found |
| 83 | } |
| 84 | } |
| 85 | if !isnil(t.tc) { |
| 86 | if sum_name in t.tc.sum_types { |
| 87 | return sum_name |
| 88 | } |
| 89 | if sum_name.contains('.') { |
| 90 | short_sum := sum_name.all_after_last('.') |
| 91 | if short_sum in t.tc.sum_types { |
| 92 | return short_sum |
| 93 | } |
| 94 | } |
| 95 | if !sum_name.contains('.') && t.cur_module.len > 0 && t.cur_module != 'main' |
| 96 | && t.cur_module != 'builtin' { |
| 97 | qsum := '${t.cur_module}.${sum_name}' |
| 98 | if qsum in t.tc.sum_types { |
| 99 | return qsum |
| 100 | } |
| 101 | } |
| 102 | if !sum_name.contains('.') { |
| 103 | mut found := '' |
| 104 | for key, _ in t.tc.sum_types { |
| 105 | if key.contains('.') && key.all_after_last('.') == sum_name { |
| 106 | if found.len > 0 && found != key { |
| 107 | found = '' |
| 108 | break |
| 109 | } |
| 110 | found = key |
| 111 | } |
| 112 | } |
| 113 | if found.len > 0 { |
| 114 | return found |
| 115 | } |
| 116 | } |
| 117 | } |
| 118 | return sum_name |
| 119 | } |
| 120 | |
| 121 | // is_sum_type_name reports whether is sum type name applies in transform. |
| 122 | fn (t &Transformer) is_sum_type_name(name string) bool { |
| 123 | if name.len == 0 { |
| 124 | return false |
| 125 | } |
| 126 | resolved := t.resolve_sum_name(name) |
| 127 | return resolved in t.sum_types |
| 128 | } |
| 129 | |
| 130 | // is_interface_type_name reports whether is interface type name applies in transform. |
| 131 | fn (t &Transformer) is_interface_type_name(name string) bool { |
| 132 | if name.len == 0 || isnil(t.tc) { |
| 133 | return false |
| 134 | } |
| 135 | clean := t.trim_pointer_type(t.normalize_type_alias(name)) |
| 136 | if clean == 'IError' || clean in t.tc.interface_names { |
| 137 | return true |
| 138 | } |
| 139 | if !clean.contains('.') && t.cur_module.len > 0 && t.cur_module != 'main' |
| 140 | && t.cur_module != 'builtin' { |
| 141 | return '${t.cur_module}.${clean}' in t.tc.interface_names |
| 142 | } |
| 143 | return false |
| 144 | } |
| 145 | |
| 146 | // interface_variant_type supports interface variant type handling for Transformer. |
| 147 | fn (t &Transformer) interface_variant_type(variant string) string { |
| 148 | if variant.contains('.') { |
| 149 | return variant |
| 150 | } |
| 151 | if variant in t.structs { |
| 152 | return variant |
| 153 | } |
| 154 | if t.cur_module.len > 0 && t.cur_module != 'main' && t.cur_module != 'builtin' { |
| 155 | qvariant := '${t.cur_module}.${variant}' |
| 156 | if qvariant in t.structs { |
| 157 | return qvariant |
| 158 | } |
| 159 | } |
| 160 | for name, _ in t.structs { |
| 161 | if name.contains('.') && name.all_after_last('.') == variant { |
| 162 | return name |
| 163 | } |
| 164 | } |
| 165 | return variant |
| 166 | } |
| 167 | |
| 168 | // smartcast_target_type supports smartcast target type handling for Transformer. |
| 169 | fn (t &Transformer) smartcast_target_type(sc SmartcastContext) string { |
| 170 | if t.is_interface_type_name(sc.sum_type_name) { |
| 171 | return t.interface_variant_type(sc.variant_name) |
| 172 | } |
| 173 | return t.resolve_variant(sc.sum_type_name, sc.variant_name) |
| 174 | } |
| 175 | |
| 176 | // sum_type_index supports sum type index handling for Transformer. |
| 177 | fn (t &Transformer) sum_type_index(sum_name string, variant string) int { |
| 178 | resolved_sum := t.resolve_sum_name(sum_name) |
| 179 | variants := t.sum_types[resolved_sum] or { |
| 180 | if !isnil(t.tc) { |
| 181 | tc_variants := t.tc.sum_types[resolved_sum] or { return 0 } |
| 182 | return sum_type_index_in_variants(tc_variants, variant) |
| 183 | } |
| 184 | return 0 |
| 185 | } |
| 186 | return sum_type_index_in_variants(variants, variant) |
| 187 | } |
| 188 | |
| 189 | // sum_type_index_in_variants supports sum type index in variants handling for transform. |
| 190 | fn sum_type_index_in_variants(variants []string, variant string) int { |
| 191 | short_variant := variant_short_name_text(variant) |
| 192 | for i, v in variants { |
| 193 | short_v := variant_short_name_text(v) |
| 194 | if v == variant || short_v == short_variant { |
| 195 | return i + 1 |
| 196 | } |
| 197 | } |
| 198 | return 0 |
| 199 | } |
| 200 | |
| 201 | // transform_is_expr transforms transform is expr data for transform. |
| 202 | fn (mut t Transformer) transform_is_expr(id flat.NodeId, node flat.Node) flat.NodeId { |
| 203 | if node.children_count == 0 { |
| 204 | return id |
| 205 | } |
| 206 | expr_id := t.a.child(&node, 0) |
| 207 | expr_type := t.node_type(expr_id) |
| 208 | clean_type0 := t.trim_pointer_type(expr_type) |
| 209 | clean_type := if clean_type0 in t.sum_types { |
| 210 | clean_type0 |
| 211 | } else { |
| 212 | t.find_sum_type_for_variant(node.value) |
| 213 | } |
| 214 | if t.is_interface_type_name(clean_type0) { |
| 215 | new_expr := t.transform_expr(expr_id) |
| 216 | object := t.make_selector_op(new_expr, '_object', 'voidptr', if expr_type.starts_with('&') { |
| 217 | .arrow |
| 218 | } else { |
| 219 | .dot |
| 220 | }) |
| 221 | return t.make_infix(.ne, object, t.a.add(.nil_literal)) |
| 222 | } |
| 223 | if clean_type.len == 0 || clean_type !in t.sum_types { |
| 224 | return t.make_bool_literal(true) |
| 225 | } |
| 226 | new_expr := t.transform_expr(expr_id) |
| 227 | if check := t.make_sum_type_pattern_check(new_expr, expr_type, clean_type, node.value) { |
| 228 | return check |
| 229 | } |
| 230 | return t.make_bool_literal(true) |
| 231 | } |
| 232 | |
| 233 | // make_sum_is_check builds make sum is check data for transform. |
| 234 | fn (mut t Transformer) make_sum_is_check(expr flat.NodeId, expr_type string, sum_name string, variant string) flat.NodeId { |
| 235 | tag := t.make_selector_op(expr, 'typ', 'int', if expr_type.starts_with('&') { |
| 236 | .arrow |
| 237 | } else { |
| 238 | .dot |
| 239 | }) |
| 240 | idx := t.make_int_literal(t.sum_type_index(sum_name, variant)) |
| 241 | return t.make_infix(.eq, tag, idx) |
| 242 | } |
| 243 | |
| 244 | // sum_variant_path supports sum variant path handling for Transformer. |
| 245 | fn (t &Transformer) sum_variant_path(sum_name string, variant string) []string { |
| 246 | mut visited := map[string]bool{} |
| 247 | return t.sum_variant_path_inner(sum_name, variant, mut visited) |
| 248 | } |
| 249 | |
| 250 | // sum_variant_path_inner supports sum variant path inner handling for Transformer. |
| 251 | fn (t &Transformer) sum_variant_path_inner(sum_name string, variant string, mut visited map[string]bool) []string { |
| 252 | resolved_sum := t.resolve_sum_name(t.trim_pointer_type(sum_name)) |
| 253 | if resolved_sum.len == 0 || resolved_sum in visited { |
| 254 | return []string{} |
| 255 | } |
| 256 | visited[resolved_sum] = true |
| 257 | if direct := t.sum_variant_name(resolved_sum, variant) { |
| 258 | return [direct] |
| 259 | } |
| 260 | variants := t.sum_types[resolved_sum] or { return []string{} } |
| 261 | for direct in variants { |
| 262 | direct_sum := t.resolve_sum_name(t.trim_pointer_type(direct)) |
| 263 | if direct_sum == resolved_sum || direct_sum !in t.sum_types { |
| 264 | continue |
| 265 | } |
| 266 | nested := t.sum_variant_path_inner(direct_sum, variant, mut visited) |
| 267 | if nested.len == 0 { |
| 268 | continue |
| 269 | } |
| 270 | mut path := []string{cap: nested.len + 1} |
| 271 | path << direct |
| 272 | path << nested |
| 273 | return path |
| 274 | } |
| 275 | return []string{} |
| 276 | } |
| 277 | |
| 278 | // make_sum_type_pattern_check builds make sum type pattern check data for transform. |
| 279 | fn (mut t Transformer) make_sum_type_pattern_check(expr flat.NodeId, expr_type string, sum_name string, variant string) ?flat.NodeId { |
| 280 | resolved_sum := t.resolve_sum_name(t.trim_pointer_type(sum_name)) |
| 281 | path := t.sum_variant_path(resolved_sum, variant) |
| 282 | if path.len == 0 { |
| 283 | return none |
| 284 | } |
| 285 | mut current := expr |
| 286 | mut current_type := expr_type |
| 287 | mut current_sum := resolved_sum |
| 288 | mut chain := flat.empty_node |
| 289 | for i, path_variant in path { |
| 290 | cmp := t.make_sum_is_check(current, current_type, current_sum, path_variant) |
| 291 | if int(chain) < 0 { |
| 292 | chain = cmp |
| 293 | } else { |
| 294 | chain = t.make_infix(.logical_and, chain, cmp) |
| 295 | } |
| 296 | if i == path.len - 1 { |
| 297 | break |
| 298 | } |
| 299 | qv := t.resolve_variant(current_sum, path_variant) |
| 300 | use_ptr := t.variant_references_sum(qv, current_sum) |
| 301 | field_type := if use_ptr { '&${qv}' } else { qv } |
| 302 | current = t.make_selector_op(current, t.sum_field_name(qv), field_type, if current_type.starts_with('&') { |
| 303 | .arrow |
| 304 | } else { |
| 305 | .dot |
| 306 | }) |
| 307 | current_type = field_type |
| 308 | current_sum = t.resolve_sum_name(t.trim_pointer_type(qv)) |
| 309 | } |
| 310 | return chain |
| 311 | } |
| 312 | |
| 313 | // transform_as_expr converts transform as expr data for transform. |
| 314 | fn (mut t Transformer) transform_as_expr(id flat.NodeId, node flat.Node) flat.NodeId { |
| 315 | if node.children_count == 0 { |
| 316 | return id |
| 317 | } |
| 318 | expr_id := t.a.child(&node, 0) |
| 319 | expr_type := t.node_type(expr_id) |
| 320 | clean_type0 := t.trim_pointer_type(expr_type) |
| 321 | clean_type := if clean_type0 in t.sum_types { |
| 322 | clean_type0 |
| 323 | } else { |
| 324 | t.find_sum_type_for_variant(node.value) |
| 325 | } |
| 326 | if clean_type.len == 0 || clean_type !in t.sum_types { |
| 327 | return t.transform_expr(expr_id) |
| 328 | } |
| 329 | qv := t.resolve_variant(clean_type, node.value) |
| 330 | if qv.len > 0 && t.normalize_type_alias(clean_type0) == t.normalize_type_alias(qv) { |
| 331 | return t.transform_expr(expr_id) |
| 332 | } |
| 333 | sc_key := t.expr_key(expr_id) |
| 334 | if sc_key.len > 0 { |
| 335 | contexts := t.smartcasts_for(sc_key) |
| 336 | mut matched_contexts := []SmartcastContext{} |
| 337 | for i, sc in contexts { |
| 338 | mut sc_variant := sc.variant_name |
| 339 | if sc.variant_name.contains('.') { |
| 340 | sc_variant = sc.variant_name.all_after_last('.') |
| 341 | } |
| 342 | mut target_variant := node.value |
| 343 | if node.value.contains('.') { |
| 344 | target_variant = node.value.all_after_last('.') |
| 345 | } |
| 346 | if sc_variant == target_variant { |
| 347 | end := i + 1 |
| 348 | matched_contexts = contexts[..end].clone() |
| 349 | } |
| 350 | } |
| 351 | if matched_contexts.len > 0 { |
| 352 | base := t.make_plain_expr_for_smartcast(expr_id) |
| 353 | return t.apply_smartcast_contexts(base, t.original_expr_type(expr_id), matched_contexts) |
| 354 | } |
| 355 | } |
| 356 | field := t.sum_field_name(qv) |
| 357 | new_expr := t.transform_expr(expr_id) |
| 358 | use_ptr := t.variant_references_sum(qv, clean_type) |
| 359 | field_typ := if use_ptr { '&${qv}' } else { qv } |
| 360 | field_sel := t.make_selector_op(new_expr, field, field_typ, if expr_type.starts_with('&') { |
| 361 | .arrow |
| 362 | } else { |
| 363 | .dot |
| 364 | }) |
| 365 | if use_ptr { |
| 366 | return t.make_prefix(.mul, field_sel) |
| 367 | } |
| 368 | return field_sel |
| 369 | } |
| 370 | |
| 371 | // wrap_sum_return_expr transforms wrap sum return expr data for transform. |
| 372 | fn (mut t Transformer) wrap_sum_return_expr(expr_id flat.NodeId) flat.NodeId { |
| 373 | was_return_expr := t.in_return_expr |
| 374 | t.in_return_expr = true |
| 375 | result := if t.cur_fn_ret_type.len == 0 || t.cur_fn_ret_type !in t.sum_types { |
| 376 | t.transform_expr(expr_id) |
| 377 | } else { |
| 378 | t.wrap_sum_value(expr_id, t.cur_fn_ret_type) |
| 379 | } |
| 380 | t.in_return_expr = was_return_expr |
| 381 | return result |
| 382 | } |
| 383 | |
| 384 | // wrap_sum_value transforms wrap sum value data for transform. |
| 385 | fn (mut t Transformer) wrap_sum_value(expr_id flat.NodeId, target_sum string) flat.NodeId { |
| 386 | resolved_sum := t.resolve_sum_name(target_sum) |
| 387 | if resolved_sum.len == 0 || resolved_sum !in t.sum_types { |
| 388 | return t.transform_expr(expr_id) |
| 389 | } |
| 390 | expr := t.a.nodes[int(expr_id)] |
| 391 | if expr.kind == .if_expr { |
| 392 | branch_type := t.if_expr_branch_result_type(expr) |
| 393 | if t.if_expr_branch_overrides_sum_target(branch_type, resolved_sum) { |
| 394 | return t.transform_expr(expr_id) |
| 395 | } |
| 396 | if lowered := t.try_expand_if_expr_value_for_type(expr_id, expr, resolved_sum) { |
| 397 | return lowered |
| 398 | } |
| 399 | } |
| 400 | expr_type := t.node_type(expr_id) |
| 401 | mut variant := expr_type |
| 402 | mut expr_smartcast := SmartcastContext{} |
| 403 | key := t.expr_key(expr_id) |
| 404 | if key.len > 0 { |
| 405 | if sc := t.find_smartcast(key) { |
| 406 | expr_smartcast = sc |
| 407 | } |
| 408 | } |
| 409 | has_expr_smartcast := expr_smartcast.expr_name.len > 0 |
| 410 | if has_expr_smartcast && t.resolve_sum_name(expr_smartcast.sum_type_name) == resolved_sum { |
| 411 | variant = t.resolve_variant(expr_smartcast.sum_type_name, expr_smartcast.variant_name) |
| 412 | } |
| 413 | if expr.kind == .prefix && expr.op == .mul && expr.children_count > 0 { |
| 414 | inner_type := t.node_type(t.a.child(&expr, 0)) |
| 415 | if inner_type.starts_with('&') { |
| 416 | variant = inner_type[1..] |
| 417 | } |
| 418 | } |
| 419 | if expr.kind == .struct_init || expr.kind == .cast_expr { |
| 420 | variant = expr.value |
| 421 | } else if expr.kind == .as_expr && expr.value.len > 0 { |
| 422 | variant = expr.value |
| 423 | } else if expr.kind == .assoc && expr.value.len > 0 { |
| 424 | variant = expr.value |
| 425 | } else if expr.kind == .assoc && expr.children_count > 0 { |
| 426 | variant = t.node_type(t.a.child(&expr, 0)) |
| 427 | } |
| 428 | if expr.kind !in [.assoc, .as_expr, .prefix] && !has_expr_smartcast |
| 429 | && t.resolve_sum_name(expr_type) == resolved_sum { |
| 430 | return t.transform_expr(expr_id) |
| 431 | } |
| 432 | if expr_type.starts_with('&') && t.resolve_sum_name(expr_type[1..]) == resolved_sum { |
| 433 | inner := t.transform_expr(expr_id) |
| 434 | deref := t.make_prefix(.mul, inner) |
| 435 | t.a.nodes[int(deref)].typ = resolved_sum |
| 436 | return deref |
| 437 | } |
| 438 | if variant.len == 0 { |
| 439 | return t.transform_expr(expr_id) |
| 440 | } |
| 441 | mut clean_variant := if variant.starts_with('&') { variant[1..] } else { variant } |
| 442 | if clean_variant.starts_with('ptr') && clean_variant.len > 3 && clean_variant[3..].contains('.') { |
| 443 | clean_variant = clean_variant[3..] |
| 444 | } |
| 445 | if clean_variant.starts_with('ptr') && clean_variant.len > 3 |
| 446 | && clean_variant[3..].contains('__') { |
| 447 | clean_variant = clean_variant[3..].replace('__', '.') |
| 448 | } |
| 449 | short_variant := t.variant_short_name(clean_variant) |
| 450 | mut matches := false |
| 451 | mut matched_variant := clean_variant |
| 452 | for v in t.sum_types[resolved_sum] { |
| 453 | short_v := t.variant_short_name(v) |
| 454 | if v == clean_variant || short_v == short_variant { |
| 455 | matches = true |
| 456 | matched_variant = v |
| 457 | break |
| 458 | } |
| 459 | } |
| 460 | if !matches { |
| 461 | return t.transform_expr(expr_id) |
| 462 | } |
| 463 | ref_variant := t.variant_references_sum(matched_variant, resolved_sum) |
| 464 | mut pointer_variant_child := flat.empty_node |
| 465 | if expr.kind == .prefix && expr.op == .mul && expr.children_count > 0 { |
| 466 | pointer_variant_child = t.a.child(&expr, 0) |
| 467 | } |
| 468 | inner := if int(pointer_variant_child) >= 0 && ref_variant { |
| 469 | t.transform_expr(pointer_variant_child) |
| 470 | } else { |
| 471 | t.transform_expr(expr_id) |
| 472 | } |
| 473 | if expr_type.starts_with('&') { |
| 474 | return t.make_sum_literal(resolved_sum, matched_variant, inner) |
| 475 | } |
| 476 | if int(pointer_variant_child) >= 0 && ref_variant { |
| 477 | return t.make_sum_literal(resolved_sum, matched_variant, inner) |
| 478 | } |
| 479 | if ref_variant { |
| 480 | return t.make_sum_literal(resolved_sum, matched_variant, inner) |
| 481 | } |
| 482 | start := t.a.children.len |
| 483 | t.a.children << inner |
| 484 | return t.a.add_node(flat.Node{ |
| 485 | kind: .cast_expr |
| 486 | value: resolved_sum |
| 487 | children_start: start |
| 488 | children_count: 1 |
| 489 | typ: resolved_sum |
| 490 | }) |
| 491 | } |
| 492 | |
| 493 | // ensure_sum_variant_ref supports ensure sum variant ref handling for Transformer. |
| 494 | fn (mut t Transformer) ensure_sum_variant_ref(value flat.NodeId, variant string) flat.NodeId { |
| 495 | mut value_type := t.node_type(value) |
| 496 | if value_type.starts_with('&') { |
| 497 | return value |
| 498 | } |
| 499 | clean_variant := if variant.starts_with('&') { variant[1..] } else { variant } |
| 500 | if value_type.len == 0 { |
| 501 | value_type = clean_variant |
| 502 | } |
| 503 | if t.expr_can_take_address(value) || t.a.nodes[int(value)].kind == .struct_init { |
| 504 | ref := t.make_prefix(.amp, value) |
| 505 | t.a.nodes[int(ref)].typ = '&${clean_variant}' |
| 506 | return ref |
| 507 | } |
| 508 | tmp_name := t.new_temp('sum_val') |
| 509 | t.pending_stmts << t.make_decl_assign_typed(tmp_name, value, value_type) |
| 510 | ref := t.make_prefix(.amp, t.make_ident(tmp_name)) |
| 511 | t.a.nodes[int(ref)].typ = '&${clean_variant}' |
| 512 | return ref |
| 513 | } |
| 514 | |
| 515 | // make_sum_literal builds make sum literal data for transform. |
| 516 | fn (mut t Transformer) make_sum_literal(sum_name string, variant string, value flat.NodeId) flat.NodeId { |
| 517 | qvariant := t.resolve_variant(sum_name, variant) |
| 518 | typ_field := t.make_sum_literal_field('typ', t.make_int_literal(t.sum_type_index(sum_name, |
| 519 | qvariant)), 'int') |
| 520 | raw_value_type := t.node_type(value) |
| 521 | value_type := if raw_value_type.starts_with('&') { |
| 522 | raw_value_type |
| 523 | } else { |
| 524 | qvariant |
| 525 | } |
| 526 | value_field := t.make_sum_literal_field(t.sum_field_name(qvariant), value, value_type) |
| 527 | start := t.a.children.len |
| 528 | t.a.children << typ_field |
| 529 | t.a.children << value_field |
| 530 | return t.a.add_node(flat.Node{ |
| 531 | kind: .struct_init |
| 532 | children_start: start |
| 533 | children_count: 2 |
| 534 | value: sum_name |
| 535 | typ: sum_name |
| 536 | }) |
| 537 | } |
| 538 | |
| 539 | // make_sum_literal_field builds make sum literal field data for transform. |
| 540 | fn (mut t Transformer) make_sum_literal_field(name string, value flat.NodeId, typ string) flat.NodeId { |
| 541 | start := t.a.children.len |
| 542 | t.a.children << value |
| 543 | return t.a.add_node(flat.Node{ |
| 544 | kind: .field_init |
| 545 | children_start: start |
| 546 | children_count: 1 |
| 547 | value: name |
| 548 | typ: typ |
| 549 | }) |
| 550 | } |
| 551 | |