@@ -29,6 +29,7 @@ type Generator struct {
2929 currentCompBody * guixast.Body // Current component body being generated
3030 currentComp * guixast.Component // Current component being generated
3131 componentParams map [string ]bool // Track current component's parameter names
32+ channelReceiveVars map [string ]string // Map local var names to channel names (e.g., "currentState" -> "StateChannel")
3233 verbose bool // Generate verbose logging statements
3334}
3435
@@ -989,14 +990,20 @@ func (g *Generator) generateConstructor(comp *guixast.Component) *ast.FuncDecl {
989990func (g * Generator ) generateRenderMethod (comp * guixast.Component ) * ast.FuncDecl {
990991 // Set up context for hoisted variable tracking
991992 g .hoistedVars = make (map [string ]bool )
993+ g .channelReceiveVars = make (map [string ]string )
992994 g .currentCompBody = comp .Body
993995
994- // Collect hoisted variable names
996+ // Collect hoisted variable names and channel receive variables
995997 if comp .Body != nil {
996998 for _ , varDecl := range comp .Body .VarDecls {
997- if len (varDecl .Names ) == 1 && len (varDecl .Values ) == 1 &&
998- g .inferTypeFromExpr (varDecl .Values [0 ]) != nil {
999- g .hoistedVars [varDecl .Names [0 ]] = true
999+ if len (varDecl .Names ) == 1 && len (varDecl .Values ) == 1 {
1000+ if g .inferTypeFromExpr (varDecl .Values [0 ]) != nil {
1001+ g .hoistedVars [varDecl .Names [0 ]] = true
1002+ } else if varDecl .Values [0 ].Left != nil && varDecl .Values [0 ].Left .ChannelOp != nil {
1003+ // Track channel receive: currentState := <-stateChannel
1004+ channelName := varDecl .Values [0 ].Left .ChannelOp .Channel
1005+ g .channelReceiveVars [varDecl .Names [0 ]] = capitalize (channelName )
1006+ }
10001007 }
10011008 }
10021009 }
@@ -1087,8 +1094,13 @@ func (g *Generator) generateBody(body *guixast.Body) ast.Expr {
10871094 canHoist := len (varDecl .Names ) == 1 && len (varDecl .Values ) == 1 &&
10881095 g .inferTypeFromExpr (varDecl .Values [0 ]) != nil
10891096
1090- if canHoist {
1091- // Hoisted field - skip initialization in Render (already done in constructor)
1097+ // Check if this is a channel receive variable (skip - will be accessed via c.current<ChannelName>)
1098+ isChannelReceive := len (varDecl .Names ) == 1 &&
1099+ g .channelReceiveVars != nil &&
1100+ g .channelReceiveVars [varDecl .Names [0 ]] != ""
1101+
1102+ if canHoist || isChannelReceive {
1103+ // Hoisted field or channel receive - skip initialization in Render
10921104 continue
10931105 } else {
10941106 // Local variable(s) - generate: name := value or n, err := value
@@ -1546,6 +1558,15 @@ func (g *Generator) generatePrimary(primary *guixast.Primary) ast.Expr {
15461558 }
15471559
15481560 if primary .Ident != "" {
1561+ // Check if it's a channel receive variable (e.g., currentState -> c.currentStateChannel)
1562+ if g .channelReceiveVars != nil {
1563+ if channelName , ok := g .channelReceiveVars [primary .Ident ]; ok {
1564+ return & ast.SelectorExpr {
1565+ X : ast .NewIdent ("c" ),
1566+ Sel : ast .NewIdent ("current" + channelName ),
1567+ }
1568+ }
1569+ }
15491570 // Check if it's a hoisted variable (stored as-is in component struct)
15501571 if g .hoistedVars != nil && g .hoistedVars [primary .Ident ] {
15511572 return & ast.SelectorExpr {
@@ -1710,7 +1731,22 @@ func (g *Generator) generateCallOrSelect(cos *guixast.CallOrSelect) ast.Expr {
17101731 }
17111732
17121733 // Build the base selector expression from base and fields
1713- var expr ast.Expr = ast .NewIdent (cos .Base )
1734+ // Check if base is a channel receive variable that needs to be replaced
1735+ var expr ast.Expr
1736+ if g .channelReceiveVars != nil {
1737+ if channelName , ok := g .channelReceiveVars [cos .Base ]; ok {
1738+ // Replace base with c.current<ChannelName>
1739+ expr = & ast.SelectorExpr {
1740+ X : ast .NewIdent ("c" ),
1741+ Sel : ast .NewIdent ("current" + channelName ),
1742+ }
1743+ } else {
1744+ expr = ast .NewIdent (cos .Base )
1745+ }
1746+ } else {
1747+ expr = ast .NewIdent (cos .Base )
1748+ }
1749+
17141750 for _ , field := range cos .Fields {
17151751 expr = & ast.SelectorExpr {
17161752 X : expr ,
0 commit comments