Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(zap_dev): Wrap interpolated identifiers in braces #23

Merged
merged 3 commits into from
Sep 24, 2023

Conversation

dnys1
Copy link
Contributor

@dnys1 dnys1 commented Sep 24, 2023

When component variables are interpolated in strings, the replacement identifier can cause invalidate Dart code to be generated if the identifier is not wrapped in braces already.

For example:

<script>
  String? value;
  String? interpolated;

  $: interpolated = '$value';
</script>

Here, the interpolated string currently becomes something like $_$v2 /* value */ which is invalid Dart code, when we really want ${_$v2 /* value */}.

When component variables are interpolated in strings, the replacement identifier can cause invalidate Dart code to be generated if the identifier is not wrapped in braces already.

For example:

```html
<script>
  String? value;
  String? interpolated;

  $: interpolated = '$value';
</script>
```

Here, the interpolated string currently becomes something like `$_$v2 /* value */` which is invalid Dart code, when we really want `${_$v2 /* value */}`.
void _patchIdentifier(
SyntacticEntity entity,
Element? target, {
bool wrapVariablesInBraces = false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solution feels pretty hacky. Open to better ways to handle it!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can handle this in visitInterpolationElement without changing _patchIdentifier by writing the braces into an empty span:

if (missingBraces) {
  _replaceRange(node.leftBracket.end, 0, '{');
}

_patchIdentifier(expression, expression.staticElement);

if (missingBraces) {
  _replaceRange(expression.end, 0, '}');
}

return;

I didn't try this so there might be an off-by-one error here, but as long as the patches are made with increasing offsets that don't overlap, this should work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worked like a charm! Very cool system here. I was confused how that could work since after _patchIdentifier, the contents have changed. Turns out it's as simple as keeping tracking of the skew 😅 brilliant!

zap_dev/lib/src/generator/generator.dart Outdated Show resolved Hide resolved
Copy link
Owner

@simolus3 simolus3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

void _patchIdentifier(
SyntacticEntity entity,
Element? target, {
bool wrapVariablesInBraces = false,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can handle this in visitInterpolationElement without changing _patchIdentifier by writing the braces into an empty span:

if (missingBraces) {
  _replaceRange(node.leftBracket.end, 0, '{');
}

_patchIdentifier(expression, expression.staticElement);

if (missingBraces) {
  _replaceRange(expression.end, 0, '}');
}

return;

I didn't try this so there might be an off-by-one error here, but as long as the patches are made with increasing offsets that don't overlap, this should work.

zap_dev/lib/src/generator/generator.dart Outdated Show resolved Hide resolved
Copy link
Owner

@simolus3 simolus3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for the PRs!

@simolus3 simolus3 merged commit 2843ad1 into simolus3:main Sep 24, 2023
4 checks passed
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.

2 participants