Skip to content

Commit eaeb52b

Browse files
authored
Prefer raw strings when possible (#2385)
In #2357 we added more complex escaping to allow creating safe string literals even when they may include single quote characters. The new implementation didn't prefer raw strings by default so use existing uses changed behavior and some tests which hardcode expected generated output a non-behavior impacting diff appears. Prefer to use actual prefixed raw strings when there are no single quotes. Existing callers passing strings allowed by the old implementation will not be impacted by the change. In the next steps of the migration calling sites will only see a behavior difference as they change their arguments. In the end all tests will be migrated to the code path which doesn't prefer raw prefixed strings, but the incremental changes will only impact tests when library code is changing.
1 parent 0857d53 commit eaeb52b

2 files changed

Lines changed: 11 additions & 7 deletions

File tree

pkgs/code_builder/lib/src/specs/expression/literal.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ Expression literalNum(num value) => LiteralExpression._('$value');
5151
/// Passing `raw: true` is recommended and will become the only option in a
5252
/// future release.
5353
Expression literalString(String value, {bool raw = false}) {
54-
if (raw) return LiteralExpression._(_escapeString(value));
54+
if (raw) return LiteralExpression._(_escapeString(value, preferRaw: raw));
5555
final escaped = value.replaceAll('\'', '\\\'').replaceAll('\n', '\\n');
5656
return LiteralExpression._("'$escaped'");
5757
}
5858

59-
String _escapeString(String value) {
59+
String _escapeString(String value, {bool preferRaw = false}) {
6060
final original = value;
6161
var hasSingleQuote = false;
6262
var hasDoubleQuote = false;
@@ -84,6 +84,10 @@ String _escapeString(String value) {
8484
return _escapeMap[char] ?? _hexLiteral(char);
8585
});
8686

87+
if (preferRaw && canBeRaw && !hasSingleQuote) {
88+
return "r'$original'";
89+
}
90+
8791
if (canBeRaw && (hasDollar || hasBackslash)) {
8892
if (!hasSingleQuote) return "r'$original'";
8993
if (!hasDoubleQuote) return 'r"$original"';

pkgs/code_builder/test/specs/code/expression_test.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,27 @@ void main() {
8181

8282
group('literalString raw', () {
8383
test('should emit a simple string', () {
84-
expect(literalString(raw: true, 'foo'), equalsDart(r"'foo'"));
84+
expect(literalString(raw: true, 'foo'), equalsDart(r"r'foo'"));
8585
});
8686

8787
test('should emit an empty string', () {
88-
expect(literalString(raw: true, ''), equalsDart("''"));
88+
expect(literalString(raw: true, ''), equalsDart(r"r''"));
8989
});
9090

9191
test('should use double quotes for just a single quote', () {
9292
expect(literalString(raw: true, "'"), equalsDart('"\'"'));
9393
});
9494

9595
test('should use single quotes for just a double quote', () {
96-
expect(literalString(raw: true, '"'), equalsDart("'\"'"));
96+
expect(literalString(raw: true, '"'), equalsDart("r'\"'"));
9797
});
9898

9999
test('should use raw string for a single backslash', () {
100100
expect(literalString(raw: true, '\\'), equalsDart("r'\\'"));
101101
});
102102

103103
test('should emit unicode characters', () {
104-
expect(literalString(raw: true, '😊'), equalsDart("'😊'"));
104+
expect(literalString(raw: true, '😊'), equalsDart(r"r'😊'"));
105105
});
106106

107107
test('should escape a carriage return in a string', () {
@@ -122,7 +122,7 @@ void main() {
122122
test('should use single quotes if it contains double quotes', () {
123123
expect(
124124
literalString(raw: true, 'foo "bar"'),
125-
equalsDart('\'foo "bar"\''),
125+
equalsDart("r'foo \"bar\"'"),
126126
);
127127
});
128128

0 commit comments

Comments
 (0)