fix: preserve multiline source expression whitespace#323
fix: preserve multiline source expression whitespace#323hjotha wants to merge 3 commits intomendixlabs:mainfrom
Conversation
Symptom: describe/exec round-trips collapsed multiline declaration and log-template expressions, producing cosmetic drift and losing source layout that users intentionally wrote. Root cause: declare initial values and log message/node expressions were rebuilt from parsed expression nodes instead of retaining source text, and template parameter gaps discarded newline-only whitespace between parameters. Fix: add SourceExpr as a small expression wrapper for retained source text, use it for declare/log/while expressions that need source preservation, serialize it back through the executor, and append newline-only trailing whitespace between log template parameters to the captured source expression. Tests: added parser coverage for multiline declare values and log template parameters with trailing blank lines; validated make build, make test, and make lint-go.
AI Code ReviewWe are reviewing a PR that adds a new The PR does not add new MDL syntax (it's about preserving existing source text) but modifies the internal representation and handling of expressions. Let's go through the checklist: Overlap & duplication
MDL syntax design
Full-stack consistency
Test coverage
Security & robustness
Scope & atomicity
Code quality
Bugs & correctness
Looking at the test case: The declare initial value is split over multiple lines with The test expects: The implementation in
The The function One potential issue: the function DECLARE $Endpoint String = @Synthetic.Endpoint The initial value starts at In the test, the expression string is: This string does not have leading or trailing whitespace (it starts with '@' and ends with ''''). So Similarly, for the log template param, we expect "toString($Count)\n\n". This string starts with 't' and ends with '\n' (two newlines). The trailing newlines would be removed by So if the original text of the expression (from the antlr context) includes trailing whitespace (like newlines) then Looking at the test: the first template parameter is It looks for the gap between the end of the current expression and the start of the next parameter (or the end of the template params). It then if the delimiter is a comma, it takes the text up to the comma. In the test, the gap between the end of the first expression and the start of the second expression is two newlines and then a comma? Actually, the input is: , {2} = $Endpoint); So after
But note: the next parameter starts at the
So the gap string is: "\n\n , {2} = $Endpoint" (but note: the actual input has two newlines, then a space, then a comma, then a space, then Then in But the test expects the source to be exactly "toString($Count)\n\n" (without the trailing space). However, note the test input has two newlines and then a comma and then a space. The gap we captured was "\n\n " (two newlines and a space). The test expects only two newlines. This might be a discrepancy. However, note the test says: "Log template parameter keeps trailing blank-line whitespace." and the test expects the source to be "toString($Count)\n\n". The actual input has two newlines and then a comma and a space. The blank line is the two newlines? The comma and space are not part of the whitespace we want to keep? We only want the whitespace between the end of the expression and the comma? The function But the test expects only the two newlines, not the space. However, note that the space after the two newlines and before the comma is not part of the "blank-line whitespace" we want to keep? The blank line is the two newlines. The space is incidental and might be considered part of the formatting. But the PR description says: "Preserve newline-only trailing whitespace between log template parameters." So we only want to preserve the newlines, not the space. This suggests that the function Looking at the test input string in the PR: , {2} = $Endpoint); There is a blank line (two newlines) between So the test input must not have a space between the two newlines and the comma? Actually, the test input as written in the PR has: , {2} = $Endpoint); There are two newlines after , {2} = $Endpoint); The line with the comma starts with two spaces? Actually, the indentation level: the WHILE block is indented by two spaces, then the LOG statement is indented by two more? But we don't have to worry because the antlr token stream will capture the exact text. Given that the test passes, we assume the implementation is correct for the test case. Now, let's check for any potential issues:
Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
…ation Adds an MDL script under mdl-examples/bug-tests/ exercising both multiline DECLARE initial values and inter-parameter blank lines in LOG template parameters. The describe → exec → describe fixpoint confirms SourceExpr-wrapped expressions retain their original whitespace. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Symptom: a plain string literal containing punctuation such as `!` or `:` could be wrapped as a SourceExpr, causing downstream log-template formatting to emit extra quoting. Root cause: shouldPreserveExpressionSource scanned every operator-like byte without tracking whether it was inside a single-quoted string literal. Fix: skip compact-operator detection while inside single-quoted literals, including doubled single-quote escapes. Tests: add visitor coverage for punctuation and escaped quotes inside string literals while keeping compact operators outside literals preserved.
|
Updated the branch with a source-preservation guard for string literals: punctuation inside single-quoted literals no longer forces
|
Part of #332.
Fixes #322.
Summary
Preserves multiline source text for declaration initial values and log expressions, including newline-only whitespace between log template parameters. Also avoids preserving plain string literals solely because their text contains punctuation such as
!or:.Root cause
The visitor rebuilt declare/log expressions from parsed expression nodes. That discarded original line breaks and inter-parameter whitespace. The source-preservation scanner also inspected operator-like bytes inside single-quoted string literals, which could wrap plain template text as a
SourceExpr.Fix
SourceExpras a source-preserving expression wrapper.buildSourceExpressionfor source-sensitive declare/log/while expressions.SourceExprthrough executor expression formatting.Tests
Added parser coverage for synthetic multiline declare/log template expressions and visitor coverage for punctuation inside string literals. Test names and fixtures are synthetic and do not reference real project microflows.
Validation
go test ./mdl/visitor -run 'TestDeclareAndLogTemplatePreserveMultilineSourceWhitespace|TestShouldPreserveExpressionSourceIgnoresStringLiteralPunctuation'make buildmake testmake lint-gomake test-integrationAgentic Code Testing
Test plan