generateMatchSwitchWithAssignment generates switch statement that assigns to varName. Example: switch x.(type) { case A: varName = "a"; case B: varName = "b" } Includes default panic with scrutinee value.
(varName string)
| 839 | // Example: switch x.(type) { case A: varName = "a"; case B: varName = "b" } |
| 840 | // Includes default panic with scrutinee value. |
| 841 | func (g *MatchCodeGen) generateMatchSwitchWithAssignment(varName string) { |
| 842 | // Generate scrutinee |
| 843 | scrutineeResult := GenerateExpr(g.Match.Scrutinee) |
| 844 | scrutineeCode := string(scrutineeResult.Output) |
| 845 | |
| 846 | // CRITICAL FIX: Always bind match value to temp var to prevent double evaluation |
| 847 | // This prevents side-effect functions (e.g., popQueue()) from executing twice: |
| 848 | // once in switch condition and once in panic clause |
| 849 | scrutineeTempVar := g.SharedTempVar("val") |
| 850 | g.Write(fmt.Sprintf("%s := %s\n", scrutineeTempVar, scrutineeCode)) |
| 851 | |
| 852 | // Check if we need type assertion (for constructor patterns) |
| 853 | needsTypeSwitch := g.hasConstructorPatterns() |
| 854 | |
| 855 | // Check if we have any bindings (to decide on temp var usage) |
| 856 | hasBindings := g.hasBindings() |
| 857 | |
| 858 | if needsTypeSwitch { |
| 859 | // Generate type switch: switch v := scrutinee.(type) or switch scrutinee.(type) |
| 860 | if hasBindings { |
| 861 | // Need temp var for bindings |
| 862 | tempVar := g.SharedTempVar("v") |
| 863 | g.scrutineeTempVar = tempVar // Store for generateArmBodyWithAssignment |
| 864 | g.Write("switch " + tempVar + " := ") |
| 865 | g.Write(scrutineeTempVar) |
| 866 | g.Write(".(type) {\n") |
| 867 | } else { |
| 868 | // No bindings - just use scrutinee.(type) without variable |
| 869 | g.Write("switch ") |
| 870 | g.Write(scrutineeTempVar) |
| 871 | g.Write(".(type) {\n") |
| 872 | } |
| 873 | } else { |
| 874 | // Generate value switch: switch scrutinee { |
| 875 | g.Write("switch ") |
| 876 | g.Write(scrutineeTempVar) |
| 877 | g.Write(" {\n") |
| 878 | } |
| 879 | |
| 880 | // Group arms by pattern type to avoid duplicate case clauses |
| 881 | // This handles guarded patterns correctly |
| 882 | g.generateGroupedCasesWithAssignment(varName, needsTypeSwitch) |
| 883 | |
| 884 | // NO DEFAULT PANIC: |
| 885 | // - Expression matches: verified exhaustive by checkExhaustiveness() |
| 886 | // - Statement matches: silent fall-through per user requirement |
| 887 | |
| 888 | g.WriteByte('}') |
| 889 | } |
| 890 | |
| 891 | // generateMatchArmWithAssignment generates a case clause with assignment to varName. |
| 892 | // Handles pattern matching, guards, and assignment generation. |
no test coverage detected