Skip to content

go: dispatch *tree.Else in GoVisitor.Visit so RPC sends the body#7592

Merged
jkschneider merged 1 commit intomainfrom
go-rpc-dispatch-else
May 7, 2026
Merged

go: dispatch *tree.Else in GoVisitor.Visit so RPC sends the body#7592
jkschneider merged 1 commit intomainfrom
go-rpc-dispatch-else

Conversation

@jkschneider
Copy link
Copy Markdown
Member

Summary

JavaSender.VisitIf constructs a synthetic *tree.Else to mirror Java's J.If.Else on the wire, but GoVisitor.Visit's type switch had no case for it. The node fell through to default: return t, so preVisit (id/prefix/markers) ran but JavaSender.VisitElse never did and the body was never sent. The receive queue desynchronized for the rest of the parse, surfacing on the Java side as either:

  • Expected CHANGE with positions in receiveList, but got ADD ... (in RpcReceiveQueue.receiveList whenever a list-typed field is the first to land on the misaligned offset), or
  • ClassCastException: org.openrewrite.java.tree.Space cannot be cast to org.openrewrite.java.tree.JRightPadded (when JavaReceiver.visitElse is the unlucky one that reads the next misaligned message).

The integ test GolangParserIntegTest.ifElseStatement was already failing on main for this reason; downstream the moderne-cli was hitting the same desync on every gorilla/mux file with an if/else past it (29 parse errors across 64 files in a 3-repo sample).

Fix

Add the dispatch entry, the matching VisitorI method, and a default GoVisitor.VisitElse that visits prefix / markers / body so language-level traversal terminates correctly.

Test plan

  • :rewrite-go:integTest — full suite green, including GolangParserIntegTest.ifElseStatement (was failing).
  • New regression test ParseProjectIfElseTest.ifElseInProjectFile — fails on the parent commit, passes here.
  • Downstream moderne-cli build over gorilla/mux + spf13/cobra + stretchr/testify: 0 parse errors across 60 files (was 29 / 64 before).

`JavaSender.VisitIf` constructs a synthetic `*tree.Else` to mirror
Java's `J.If.Else` on the wire, but `GoVisitor.Visit`'s type switch had
no case for it — the node fell through to `default: return t`, so
preVisit (id/prefix/markers) ran but `JavaSender.VisitElse` never did
and the body was never sent. The receive queue desynchronized for the
rest of the parse, surfacing as `Expected CHANGE with positions in
receiveList` or `Space cannot be cast to JRightPadded` depending on
which sibling node tripped first.

Add the dispatch entry, the matching `VisitorI` method, and a default
`GoVisitor.VisitElse` that visits prefix / markers / body so
language-level traversal terminates correctly.
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite May 7, 2026
@jkschneider jkschneider merged commit b2dd481 into main May 7, 2026
1 check passed
@jkschneider jkschneider deleted the go-rpc-dispatch-else branch May 7, 2026 02:43
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant