Skip to content

fix(lang-core): keep multi-line ternaries intact in mergeStatements - #866

Open
serhiizghama wants to merge 2 commits into
thesysdev:mainfrom
serhiizghama:fix/merge-multiline-ternary
Open

fix(lang-core): keep multi-line ternaries intact in mergeStatements#866
serhiizghama wants to merge 2 commits into
thesysdev:mainfrom
serhiizghama:fix/merge-multiline-ternary

Conversation

@serhiizghama

Copy link
Copy Markdown

Closes #821.

A statement written as a multi-line ternary survives parse(), but mergeStatements() was silently dropping both branches even when the patch never touched that statement:

a = $ok
  ? Title("Yes")
  : Title("No")

becomes a = $ok after merging an unrelated patch.

The cause is the third statement splitter. split() in statements.ts and scanNewCompleted() in parser.ts both know that a ? / : continuation line belongs to the same statement (they track ternaryDepth and peek past the newline), but mergeStatements() re-splits the existing program with splitStatementSource() in merge.ts, which only tracked bracket depth and broke on every depth-0 newline. The ? ... / : ... fragments then failed the Ident = expression shape check and were discarded without an error.

Went with direction 1 from the issue: gave splitStatementSource() the same ternary handling — track ternary depth at bracket depth 0, and before treating a depth-0 newline as a boundary, skip it if we are mid-ternary or the next meaningful character is a ?. Didn't unify onto split() (direction 2) because merge needs the raw source slices to round-trip the statements, and the token splitter throws that text away.

Added two tests next to the existing merge cases: the issue repro (untouched ternary stays intact) and the inverse (a patch targeting the ternary still replaces it). The first fails on the current splitter. Full lang-core suite is green, tsc/eslint/prettier clean.

splitStatementSource re-split the existing program with a char-level splitter that broke on every depth-0 newline, unlike split()/scanNewCompleted() which keep a ternary's ?/: continuation lines with the statement. So an untouched multi-line ternary lost both branches on merge. Track ternary depth and peek for a ? continuation, mirroring split().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mergeStatements() silently corrupts multi-line ternary statements that parse() accepts (statement-splitter inconsistency)

1 participant