diff options
-rw-r--r-- | src/js_ast.zig | 11 | ||||
-rw-r--r-- | src/js_printer.zig | 10 | ||||
-rw-r--r-- | test/bundler/bundler_string.test.ts | 52 |
3 files changed, 63 insertions, 10 deletions
diff --git a/src/js_ast.zig b/src/js_ast.zig index 58f5efae2..cdf7a3ad9 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -2176,7 +2176,7 @@ pub const E = struct { return @ptrCast([*]const u16, @alignCast(@alignOf(u16), this.data.ptr))[0..this.data.len]; } - pub fn resovleRopeIfNeeded(this: *String, allocator: std.mem.Allocator) void { + pub fn resolveRopeIfNeeded(this: *String, allocator: std.mem.Allocator) void { if (this.next == null or !this.isUTF8()) return; var str = this.next; var bytes = std.ArrayList(u8).initCapacity(allocator, this.rope_len) catch unreachable; @@ -2191,7 +2191,7 @@ pub const E = struct { } pub fn slice(this: *String, allocator: std.mem.Allocator) []const u8 { - this.resovleRopeIfNeeded(allocator); + this.resolveRopeIfNeeded(allocator); return this.string(allocator) catch unreachable; } @@ -2419,6 +2419,7 @@ pub const E = struct { } if (part.tail.len() > 0) { + head.data.e_string.resolveRopeIfNeeded(allocator); head.data.e_string.push(Expr.init(E.String, part.tail, part.tail_loc).data.e_string); } @@ -2445,7 +2446,7 @@ pub const E = struct { if (parts.items.len == 0) { parts.deinit(); - head.data.e_string.resovleRopeIfNeeded(allocator); + head.data.e_string.resolveRopeIfNeeded(allocator); return head; } @@ -5157,8 +5158,8 @@ pub const Expr = struct { switch (right) { .e_string => |r| { equality.ok = true; - r.resovleRopeIfNeeded(allocator); - l.resovleRopeIfNeeded(allocator); + r.resolveRopeIfNeeded(allocator); + l.resolveRopeIfNeeded(allocator); equality.equal = r.eql(E.String, l); }, .e_null, .e_undefined => { diff --git a/src/js_printer.zig b/src/js_printer.zig index 2a68135c1..e6d04a7c0 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -2507,7 +2507,7 @@ fn NewPrinter( } }, .e_string => |e| { - e.resovleRopeIfNeeded(p.options.allocator); + e.resolveRopeIfNeeded(p.options.allocator); p.addSourceMapping(expr.loc); // If this was originally a template literal, print it as one as long as we're not minifying @@ -2541,7 +2541,7 @@ fn NewPrinter( p.print("`"); if (e.head.isPresent()) { - e.head.resovleRopeIfNeeded(p.options.allocator); + e.head.resolveRopeIfNeeded(p.options.allocator); p.printStringContent(&e.head, '`'); } @@ -2551,7 +2551,7 @@ fn NewPrinter( p.printExpr(part.value, .lowest, ExprFlag.None()); p.print("}"); if (part.tail.isPresent()) { - part.tail.resovleRopeIfNeeded(p.options.allocator); + part.tail.resolveRopeIfNeeded(p.options.allocator); p.printStringContent(&part.tail, '`'); } } @@ -3205,7 +3205,7 @@ fn NewPrinter( .e_string => |key| { p.addSourceMapping(_key.loc); if (key.isUTF8()) { - key.resovleRopeIfNeeded(p.options.allocator); + key.resolveRopeIfNeeded(p.options.allocator); p.printSpaceBeforeIdentifier(); var allow_shorthand: bool = true; // In react/cjs/react.development.js, there's part of a function like this: @@ -3453,7 +3453,7 @@ fn NewPrinter( switch (property.key.data) { .e_string => |str| { - str.resovleRopeIfNeeded(p.options.allocator); + str.resolveRopeIfNeeded(p.options.allocator); p.addSourceMapping(property.key.loc); if (str.isUTF8()) { diff --git a/test/bundler/bundler_string.test.ts b/test/bundler/bundler_string.test.ts index c70b83686..5a6861a05 100644 --- a/test/bundler/bundler_string.test.ts +++ b/test/bundler/bundler_string.test.ts @@ -134,4 +134,56 @@ describe("bundler", () => { }, ); } + + itBundled("string/TemplateFolding", { + files: { + "entry.js": /* js */ ` + const s1 = "hello"; + \`\${s1} world\`; + console.log(s1); + + const s2 = \`hello\`; + console.log(s2); + const s3 = \`\${s2} world \${s1}\`; + console.log(s3); + + const s4 = \`\${s1}\${s2}\${s3}\`; + console.log(s4); + + const s5 = \`ππ\`; + console.log(s5); + const s6 = \`\${s5} π \${s1}\`; + console.log(s6); + + const s7 = \`\${s1}\${s2}\${s3}\${s4}\${s5}\${s6}\`; + console.log(s7); + + const hexCharacters = "a-f\\d"; + console.log(hexCharacters); + const match3or4Hex = \`#?[\${hexCharacters}]{3}[\${hexCharacters}]?\`; + console.log(match3or4Hex); + const match6or8Hex = \`#?[\${hexCharacters}]{6}([\${hexCharacters}]{2})?\`; + console.log(match6or8Hex); + const nonHexChars = new RegExp(\`[^#\${hexCharacters}]\`, "gi"); + console.log(nonHexChars); + const validHexSize = new RegExp(\`^\${match3or4Hex}\$|^\${match6or8Hex}$\`, "i"); + console.log(validHexSize); + `, + }, + bundling: false, + run: { + stdout: `hello + hello + hello world hello + hellohellohello world hello + ππ + ππ π hello + hellohellohello world hellohellohellohello world helloππππ π hello + a-f\d + #?[a-f\d]{3}[a-f\d]? + #?[a-f\d]{6}([a-f\d]{2})? + /[^#a-f\d]/gi + /^#?[a-f\d]{3}[a-f\d]?$|^#?[a-f\d]{6}([a-f\d]{2})?$/i`, + }, + }); }); |