Commit 5743047
authored
fix: prevent ASI in wrapCode causing refactoring to fail (#41727)
## Description
When a UI module containing a custom widget is instantiated in an app,
the `inputs` references inside the custom widget's `defaultModel`
property are not refactored. For example, `inputs.title` should become
`Commons1.inputs.title` but remains unchanged.
**Root cause:** The `entityRefactorFromCode` function in the AST package
passes raw binding content (which may have leading whitespace/newlines)
directly to `wrapCode` without sanitization. `wrapCode` wraps code as
`(function() { return ${code} })`. When the binding content starts with
a newline followed by `{` (common in custom widget `defaultModel` which
contains multi-line object literals), JavaScript's Automatic Semicolon
Insertion (ASI) rule inserts a semicolon after `return`. This causes `{`
to be parsed as a block statement instead of an object literal,
resulting in a `SyntaxError`. The error is silently swallowed in
`AstServiceCEImpl.refactorNameInDynamicBindings`, leaving the binding
unrefactored.
**Fix:** Trim leading whitespace from the script in
`entityRefactorFromCode` before passing it to `wrapCode`, so `{` lands
on the same line as `return` (preventing ASI). The leading whitespace is
restored after unwrapping to preserve the original content. This fix is
localized to `entityRefactorFromCode` — `wrapCode` itself is unchanged
because other consumers (linting, ActionCreator, etc.) pass
multi-statement evaluation scripts through it, and those would break if
the return expression were parenthesized. Also replaces the magic-number
slicing in `unwrapCode` (flagged as tech-debt) with named constants.
Fixes #32841
Fixes
https://linear.app/appsmith/issue/APP-15087/bug-ast-fails-to-refactor-if-moustache-binding-starts-with-a-new-line
**TDD verification:**
| Phase | Result |
|-------|--------|
| Red: multi-line object literal test | Failed as expected (`isSuccess:
false`) |
| Green: applied localized fix in `entityRefactorFromCode` | All 73
tests across 4 AST suites pass |
| No regression to `wrapCode` consumers | `wrapCode` output is identical
to original |
## Automation
/ok-to-test tags="@tag.All"
### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/24177924705>
> Commit: 76a1a67
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=24177924705&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Thu, 09 Apr 2026 09:10:21 UTC
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Tests**
* Added comprehensive test coverage for code entity refactoring
functionality.
* **Refactor**
* Improved code wrapping logic with named constants for better
maintainability.
* Enhanced preservation of whitespace formatting in code
transformations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent 306f25f commit 5743047
2 files changed
Lines changed: 95 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
795 | 796 | | |
796 | 797 | | |
797 | 798 | | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
350 | 350 | | |
351 | 351 | | |
352 | 352 | | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
353 | 356 | | |
354 | | - | |
355 | | - | |
356 | | - | |
357 | | - | |
358 | | - | |
| 357 | + | |
359 | 358 | | |
360 | 359 | | |
361 | | - | |
362 | | - | |
363 | 360 | | |
364 | | - | |
365 | | - | |
366 | | - | |
| 361 | + | |
367 | 362 | | |
368 | 363 | | |
369 | 364 | | |
| |||
486 | 481 | | |
487 | 482 | | |
488 | 483 | | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
489 | 490 | | |
490 | | - | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
491 | 495 | | |
492 | 496 | | |
493 | 497 | | |
| |||
572 | 576 | | |
573 | 577 | | |
574 | 578 | | |
575 | | - | |
| 579 | + | |
576 | 580 | | |
577 | 581 | | |
578 | 582 | | |
| |||
0 commit comments