Skip to content

Add fullEscape argument to literalString#2352

Open
natebosch wants to merge 6 commits intomainfrom
literal-string-doc
Open

Add fullEscape argument to literalString#2352
natebosch wants to merge 6 commits intomainfrom
literal-string-doc

Conversation

@natebosch
Copy link
Copy Markdown
Member

@natebosch natebosch commented Mar 27, 2026

Expand the doc with a more explicit description of the treatment of the
input and it's relationship to the source vs content of the result. Add
a fullEscape argument to replace raw which accomplishes nearly the
same, but restricts to input strings without single quotes. Document
this as the path to create a string literal with matching content
instead of matching source.

Add carriage returns to the set of escaped characters in non-fully
escaped single quoted strings. Other whitespace characters could be
escaped for clarity, but aren't needed for correctness. The full escape
path does escape other whitespace characters for clarity.

Closes #2350

Carriage returns, newlines, and unescaped single quotes, are all invalid
characters in any single quoted string literal.

Closes #2350

Expand the doc with a more explicit section describing that the
resulting strings may included interpolation and that `raw` is the
intended solution to write a literal based on the intended content
instead of the intended source.
@natebosch natebosch requested a review from kevmoo March 27, 2026 22:19
@natebosch natebosch requested a review from a team as a code owner March 27, 2026 22:19
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

Package publishing

Package Version Status Publish tag (post-merge)
package:bazel_worker 1.1.5 already published at pub.dev
package:benchmark_harness 2.4.0 already published at pub.dev
package:boolean_selector 2.1.2 already published at pub.dev
package:browser_launcher 1.2.0-wip WIP (no publish necessary)
package:cli_config 0.2.1-wip WIP (no publish necessary)
package:cli_util 0.5.0-wip WIP (no publish necessary)
package:clock 1.1.3-wip WIP (no publish necessary)
package:code_builder 4.11.2-wip WIP (no publish necessary)
package:coverage 1.15.0 already published at pub.dev
package:csslib 1.0.2 already published at pub.dev
package:extension_discovery 2.1.0 already published at pub.dev
package:file 7.0.2-wip WIP (no publish necessary)
package:file_testing 3.1.0-wip WIP (no publish necessary)
package:glob 2.1.3 already published at pub.dev
package:graphs 2.4.0-wip WIP (no publish necessary)
package:html 0.15.7-wip WIP (no publish necessary)
package:io 1.1.0-wip WIP (no publish necessary)
package:json_rpc_2 4.1.0 already published at pub.dev
package:markdown 7.3.1 already published at pub.dev
package:mime 2.1.0-wip WIP (no publish necessary)
package:oauth2 2.0.5 already published at pub.dev
package:package_config 2.3.0-wip WIP (no publish necessary)
package:pool 1.5.2 already published at pub.dev
package:process 5.0.5 (error) pubspec version (5.0.5) and changelog (5.0.6-wip) don't agree
package:pub_semver 2.2.0 already published at pub.dev
package:pubspec_parse 1.6.0-wip WIP (no publish necessary)
package:source_map_stack_trace 2.1.3-wip WIP (no publish necessary)
package:source_maps 0.10.14-wip WIP (no publish necessary)
package:source_span 1.10.2 already published at pub.dev
package:sse 4.2.0-wip (error) pubspec version (4.2.0-wip) and changelog (4.2.0) don't agree
package:stack_trace 1.12.2-wip (error) pubspec version (1.12.2-wip) and changelog (1.12.2-dev) don't agree
package:stream_channel 2.1.4 already published at pub.dev
package:stream_transform 2.1.2-wip WIP (no publish necessary)
package:string_scanner 1.4.2-wip WIP (no publish necessary)
package:term_glyph 1.2.3-wip WIP (no publish necessary)
package:test_reflective_loader 0.6.0 ready to publish test_reflective_loader-v0.6.0
package:timing 1.0.2 already published at pub.dev
package:unified_analytics 8.0.14 already published at pub.dev
package:watcher 1.2.2-wip WIP (no publish necessary)
package:yaml 3.1.3 already published at pub.dev
package:yaml_edit 2.2.4 already published at pub.dev

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

PR Health

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

Coverage ⚠️
File Coverage
pkgs/code_builder/lib/src/specs/expression/literal.dart 💔 Not covered

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

Unused Dependencies ⚠️
Package Status
code_builder
❗ Show Issues
These packages may be unused, or you may be using assets from these packages:
* build
* source_gen

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
code_builder Non-Breaking 4.11.1 4.11.2-wip 4.11.2-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/bazel_worker/benchmark/benchmark.dart
pkgs/coverage/lib/src/coverage_options.dart
pkgs/html/example/main.dart
pkgs/html/lib/dom.dart
pkgs/html/lib/dom_parsing.dart
pkgs/html/lib/html_escape.dart
pkgs/html/lib/parser.dart
pkgs/html/lib/src/constants.dart
pkgs/html/lib/src/encoding_parser.dart
pkgs/html/lib/src/html_input_stream.dart
pkgs/html/lib/src/list_proxy.dart
pkgs/html/lib/src/query_selector.dart
pkgs/html/lib/src/token.dart
pkgs/html/lib/src/tokenizer.dart
pkgs/html/lib/src/treebuilder.dart
pkgs/html/lib/src/utils.dart
pkgs/html/test/dom_test.dart
pkgs/html/test/parser_feature_test.dart
pkgs/html/test/parser_test.dart
pkgs/html/test/selectors/level1_baseline_test.dart
pkgs/html/test/selectors/level1_lib.dart
pkgs/html/test/selectors/selectors.dart
pkgs/html/test/support.dart
pkgs/html/test/tokenizer_test.dart
pkgs/html/test/trie_test.dart
pkgs/html/tool/generate_trie.dart
pkgs/pubspec_parse/test/git_uri_test.dart
pkgs/watcher/test/custom_watcher_factory_test.dart

This check can be disabled by tagging the PR with skip-license-check.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the code_builder package to escape carriage return characters in the literalString function, alongside documentation improvements and a new test case. Feedback highlights a critical omission regarding backslash escaping, which could result in invalid Dart source code, and provides a specific code suggestion to resolve this.

Saying triple quoted strings are "unsupported" might make it seem like
you can't pass it to this function which isn't the intended meaning.
Copy link
Copy Markdown
Member

@kevmoo kevmoo left a comment

Choose a reason for hiding this comment

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

The relationship is more clear between the argument _content_ and the
result _source_.
We may want to deprecate the `raw` argument.
@natebosch natebosch changed the title Escape carriage returns in literalString Add fullEscape argument to literalString Apr 2, 2026
return LiteralExpression._("${raw ? 'r' : ''}'$escaped'");
}

String _escapeString(String value) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks familiar 😁

Copy link
Copy Markdown
Member

@kevmoo kevmoo left a comment

Choose a reason for hiding this comment

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

SHIP IT!

@natebosch
Copy link
Copy Markdown
Member Author

Some ongoing discussion about this API.

Considering now whether it makes more sense to make a breaking change and use this escaping by default, with no option for the old behavior. I don't see any discussion about the intended use case when we added literalString dart-archive/code_builder#133
There wasn't discussion about the use cases when we added the raw string argument. dart-archive/code_builder#152

The only internal usage I can find doesn't appear to me to care about specifically allowing interpolation, and there are other code patterns possible to generate in place of interpolation. Folding down to the default safe behavior might be better UX.

@kevmoo
Copy link
Copy Markdown
Member

kevmoo commented Apr 2, 2026

I'd rather have the breaking change, honestly.

The fact that the current code allows bad output is really...bad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants