diff options
author | 2023-05-18 10:52:34 -0700 | |
---|---|---|
committer | 2023-05-18 10:52:34 -0700 | |
commit | 621232c197c0f6f562061e976ae39301cf85897f (patch) | |
tree | 3d282824b2cf6c15136f5096b4c898609949d4aa /src/js_ast.zig | |
parent | 642b3978a6ab518c717fce36acc66004b7dd09f5 (diff) | |
download | bun-621232c197c0f6f562061e976ae39301cf85897f.tar.gz bun-621232c197c0f6f562061e976ae39301cf85897f.tar.zst bun-621232c197c0f6f562061e976ae39301cf85897f.zip |
use raw template contents for tagged templates (#2937)
* use raw template contents when tagged
* use union for template contents
* pointer to cooked contents
* raw if suffix
* fix and don't skip test
Diffstat (limited to 'src/js_ast.zig')
-rw-r--r-- | src/js_ast.zig | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/src/js_ast.zig b/src/js_ast.zig index fdd220926..a3fb81402 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -2358,13 +2358,23 @@ pub const E = struct { pub const TemplatePart = struct { value: ExprNodeIndex, tail_loc: logger.Loc, - tail: E.String, + tail: Template.Contents, }; pub const Template = struct { tag: ?ExprNodeIndex = null, - head: E.String, parts: []TemplatePart = &([_]TemplatePart{}), + head: Contents, + + pub const Contents = union(Tag) { + cooked: E.String, + raw: string, + + const Tag = enum { + cooked, + raw, + }; + }; /// "`a${'b'}c`" => "`abc`" pub fn fold( @@ -2372,7 +2382,7 @@ pub const E = struct { allocator: std.mem.Allocator, loc: logger.Loc, ) Expr { - if (this.tag != null or !this.head.isUTF8()) { + if (this.tag != null or (this.head == .cooked and !this.head.cooked.isUTF8())) { // we only fold utf-8/ascii for now return Expr{ .data = .{ @@ -2382,14 +2392,17 @@ pub const E = struct { }; } + std.debug.assert(this.head == .cooked); + if (this.parts.len == 0) { - return Expr.init(E.String, this.head, loc); + return Expr.init(E.String, this.head.cooked, loc); } var parts = std.ArrayList(TemplatePart).initCapacity(allocator, this.parts.len) catch unreachable; - var head = Expr.init(E.String, this.head, loc); + var head = Expr.init(E.String, this.head.cooked, loc); for (this.parts) |part_| { var part = part_; + std.debug.assert(part.tail == .cooked); switch (part.value.data) { .e_number => { @@ -2412,28 +2425,29 @@ pub const E = struct { else => {}, } - if (part.value.data == .e_string and part.tail.isUTF8() and part.value.data.e_string.isUTF8()) { + if (part.value.data == .e_string and part.tail.cooked.isUTF8() and part.value.data.e_string.isUTF8()) { if (parts.items.len == 0) { if (part.value.data.e_string.len() > 0) { head.data.e_string.push(part.value.data.e_string); } - if (part.tail.len() > 0) { + if (part.tail.cooked.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); + head.data.e_string.push(Expr.init(E.String, part.tail.cooked, part.tail_loc).data.e_string); } continue; } else { var prev_part = &parts.items[parts.items.len - 1]; + std.debug.assert(prev_part.tail == .cooked); - if (prev_part.tail.isUTF8()) { + if (prev_part.tail.cooked.isUTF8()) { if (part.value.data.e_string.len() > 0) { - prev_part.tail.push(part.value.data.e_string); + prev_part.tail.cooked.push(part.value.data.e_string); } - if (part.tail.len() > 0) { - prev_part.tail.push(Expr.init(E.String, part.tail, part.tail_loc).data.e_string); + if (part.tail.cooked.len() > 0) { + prev_part.tail.cooked.push(Expr.init(E.String, part.tail.cooked, part.tail_loc).data.e_string); } } else { parts.appendAssumeCapacity(part); @@ -2455,7 +2469,7 @@ pub const E = struct { E.Template{ .tag = null, .parts = parts.items, - .head = head.data.e_string.*, + .head = .{ .cooked = head.data.e_string.* }, }, loc, ); @@ -7091,7 +7105,10 @@ pub const Macro = struct { return toStringValue(this, ctx, str.*); }, .e_template => |template| { - const str = template.head; + const str = switch (template.head) { + .cooked => |cooked| cooked, + .raw => |raw| E.String.init(raw), + }; if (str.isBlank()) { return JSC.ZigString.init("").toValue(ctx.ptr()).asRef(); @@ -7134,8 +7151,10 @@ pub const Macro = struct { return JSBindings.toStringValue(this, ctx, str.*); }, .e_template => |template| { - return JSBindings.toStringValue(this, ctx, template.head); - // return JSBindings.toTemplatePrimitive(this, ctx, template.*); + return switch (template.head) { + .cooked => |cooked| JSBindings.toStringValue(this, ctx, cooked), + .raw => |raw| JSBindings.toStringValue(this, ctx, E.String.init(raw)), + }; }, .e_number => |number| { return JSBindings.toNumberValue(this, number); |