aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/js_lexer.zig6
-rw-r--r--src/js_printer.zig236
-rw-r--r--src/string_immutable.zig30
3 files changed, 258 insertions, 14 deletions
diff --git a/src/js_lexer.zig b/src/js_lexer.zig
index 409b3a269..bd018a254 100644
--- a/src/js_lexer.zig
+++ b/src/js_lexer.zig
@@ -1530,9 +1530,9 @@ pub fn isIdentifierUTF16(text: JavascriptString) bool {
var i: usize = 0;
while (i < n) : (i += 1) {
- var r1 = text[i];
+ var r1 = @intCast(i32, text[i]);
if (r1 >= 0xD800 and r1 <= 0xDBFF and i + 1 < n) {
- const r2 = text[i + 1];
+ const r2 = @intCast(i32, text[i + 1]);
if (r2 >= 0xDC00 and r2 <= 0xDFFF) {
r1 = (r1 << 10) + r2 + (0x10000 - (0xD800 << 10) - 0xDC00);
i += 1;
@@ -1543,7 +1543,7 @@ pub fn isIdentifierUTF16(text: JavascriptString) bool {
return false;
}
} else {
- if (!isIDentifierContinue(@intCast(u21, r1))) {
+ if (!isIdentifierContinue(@intCast(u21, r1))) {
return false;
}
}
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 096a141ca..62390f99a 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -240,7 +240,10 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.print(";\n");
}
pub fn printSemicolonIfNeeded(p: *Printer) void {
- notimpl();
+ if (p.needs_semicolon) {
+ p.print(";");
+ p.needs_semicolon = false;
+ }
}
pub fn printSpaceBeforeIdentifier(
p: *Printer,
@@ -264,29 +267,139 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
}
pub fn printBody(p: *Printer, stmt: Stmt) void {
- notimpl();
+ switch (stmt.data) {
+ .s_block => |block| {
+ p.printSpace();
+ p.printBlock(stmt.loc, block.stmts);
+ p.printNewline();
+ },
+ else => {
+ p.printNewline();
+ p.options.indent += 1;
+ p.printStmt(stmt) catch unreachable;
+ p.options.indent -= 1;
+ },
+ }
}
pub fn printBlock(p: *Printer, loc: logger.Loc, stmts: []Stmt) void {
- notimpl();
+ p.addSourceMapping(loc);
+ p.print("{");
+ p.printNewline();
+
+ p.options.indent += 1;
+ for (stmts) |stmt| {
+ p.printSemicolonIfNeeded();
+ p.printStmt(stmt) catch unreachable;
+ }
+ p.options.indent -= 1;
+ p.needs_semicolon = false;
+
+ p.printIndent();
+ p.print("}");
}
pub fn printDecls(p: *Printer, keyword: string, decls: []G.Decl, flags: ExprFlag) void {
- notimpl();
+ p.print(keyword);
+ p.printSpace();
+
+ var i: usize = 0;
+
+ while (i < decls.len) : (i += 1) {
+ if (i != 0) {
+ p.print(",");
+ p.printSpace();
+ }
+
+ const decl = decls[i];
+
+ p.printBinding(decl.binding);
+
+ if (decl.value) |value| {
+ p.printSpace();
+ p.print("=");
+ p.printSpace();
+ p.printExpr(value, .comma, ExprFlag.None());
+ }
+ }
}
// noop for now
pub fn addSourceMapping(p: *Printer, loc: logger.Loc) void {}
pub fn printSymbol(p: *Printer, ref: Ref) void {
- notimpl();
+ const name = p.renamer.nameForSymbol(ref);
+
+ p.printIdentifier(name);
}
pub fn printClauseAlias(p: *Printer, alias: string) void {
- notimpl();
+ if (js_lexer.isIdentifier(alias)) {
+ p.printSpaceBeforeIdentifier();
+ p.printIdentifier(alias);
+ } else {
+ p.printQuotedUTF8(alias, false);
+ }
}
+
+ pub fn printFnArgs(p: *Printer, args: []G.Arg, has_rest_arg: bool, is_arrow: bool) void {
+ const wrap = true;
+
+ if (wrap) {
+ p.print("(");
+ }
+
+ var i: usize = 0;
+ while (i < args.len) : (i += 1) {
+ if (i != 0) {}
+
+ if (has_rest_arg and i + 1 == args.len) {
+ p.print("...");
+ }
+ const arg = args[i];
+
+ p.printBinding(arg.binding);
+ if (arg.default) |default| {
+ p.printSpace();
+ p.print("=");
+ p.printSpace();
+ p.printExpr(default, .comma, ExprFlag.None());
+ }
+ }
+
+ if (wrap) {
+ p.print(")");
+ }
+ }
+
pub fn printFunc(p: *Printer, func: G.Fn) void {
- notimpl();
+ p.printFnArgs(func.args, func.flags.has_rest_arg, false);
+ p.printSpace();
+ p.printBlock(func.body.?.loc, func.body.?.stmts);
}
pub fn printClass(p: *Printer, class: G.Class) void {
- notimpl();
+ if (class.extends) |extends| {}
+
+ p.printSpace();
+
+ p.addSourceMapping(class.body_loc);
+ p.print("{");
+ p.printNewline();
+ p.options.indent += 1;
+
+ for (class.properties) |item| {
+ p.printSemicolonIfNeeded();
+ p.printIndent();
+ p.printProperty(item);
+
+ if (item.value == null) {
+ p.printSemicolonAfterStatement();
+ } else {
+ p.printNewline();
+ }
+ }
+
+ p.needs_semicolon = false;
+ p.options.indent -= 1;
+ p.printIndent();
+ p.print("}");
}
pub fn bestQuoteCharForString(p: *Printer, str: anytype, allow_backtick: bool) u8 {
@@ -1474,8 +1587,109 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
p.print(")");
}
- pub fn printProperty(p: *Printer, prop: G.Property) void {
- notimpl();
+ pub fn printProperty(p: *Printer, item: G.Property) void {
+ if (item.kind == .spread) {
+ p.print("...");
+ p.printExpr(item.value.?, .comma, ExprFlag.None());
+ }
+
+ if (item.flags.is_static) {
+ p.print("static");
+ p.printSpace();
+ }
+
+ switch (item.kind) {
+ .get => {
+ p.printSpaceBeforeIdentifier();
+ p.print("get");
+ p.printSpace();
+ },
+ .set => {
+ p.printSpaceBeforeIdentifier();
+ p.print("set");
+ p.printSpace();
+ },
+ else => {},
+ }
+
+ if (item.value) |val| {
+ switch (val.data) {
+ .e_function => |func| {
+ if (item.flags.is_method) {
+ p.printSpaceBeforeIdentifier();
+ p.print("set");
+ p.printSpace();
+ }
+
+ if (func.func.flags.is_generator) {
+ p.print("*");
+ }
+ },
+ else => {},
+ }
+ }
+
+ if (item.flags.is_computed) {
+ p.print("[");
+ p.printExpr(item.key.?, .comma, ExprFlag.None());
+ p.print("]");
+
+ if (item.value) |val| {
+ switch (val.data) {
+ .e_function => |func| {
+ if (item.flags.is_method) {
+ p.printFunc(func.func);
+ return;
+ }
+ },
+ else => {},
+ }
+
+ p.print(":");
+ p.printSpace();
+ p.printExpr(val, .comma, ExprFlag.None());
+ }
+
+ if (item.initializer) |initial| {
+ p.printSpace();
+ p.print("=");
+ p.printSpace();
+ p.printExpr(initial, .comma, ExprFlag.None());
+ }
+ return;
+ }
+
+ switch (item.key.?.data) {
+ .e_private_identifier => |key| {
+ p.printSymbol(key.ref);
+ },
+ .e_string => |key| {
+ p.addSourceMapping(item.key.?.loc);
+ if (p.canPrintIdentifierUTF16(key.value)) {
+ p.printSpaceBeforeIdentifier();
+ p.printIdentifierUTF16(key.value) catch unreachable;
+
+ // Use a shorthand property if the names are the same
+ if (item.value) |val| {
+ switch (val.data) {
+ .e_identifier => |e| {
+ const name = p.renamer.nameForSymbol(e.ref);
+ // if (strings) {}
+ },
+ .e_import_identifier => |e| {},
+ else => {},
+ }
+ } else {}
+ }
+ },
+ else => {},
+ }
+
+ if (item.kind != .normal) {}
+
+ if (item.value) |val| {}
+
+ if (item.initializer) |initial| {}
}
pub fn printBinding(p: *Printer, binding: Binding) void {
notimpl();
@@ -2114,7 +2328,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
continue;
}
- const width = std.unicode.utf8Encode(c, temp);
+ const width = try std.unicode.utf8Encode(c, &temp);
p.print(temp[0..width]);
}
}
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index c1197e6ef..14569b5a9 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -89,6 +89,36 @@ pub fn eqlUtf16(comptime self: string, other: JavascriptString) bool {
return std.mem.eql(u16, std.unicode.utf8ToUtf16LeStringLiteral(self), other);
}
+pub fn utf16EqlString(text: []u16, str: string) bool {
+ if (text.len > str.len) {
+ // Strings can't be equal if UTF-16 encoding is longer than UTF-8 encoding
+ return false;
+ }
+
+ var temp = [4]byte{ 0, 0, 0, 0 };
+ const n = text.len;
+}
+
+pub fn encodeWTF8Rune(p: []byte, b: u8) u3 {
+ // Negative values are erroneous. Making it unsigned addresses the problem.
+ const i = @intCast(u32, b);
+ switch (i) {
+ 0...0x7F => {
+ p[0] = b;
+ return 1;
+ },
+ (0x7FF + 1)...0xFFFF => {
+ std.debug.panic("emoji not implemented yet!", .{});
+ },
+ (0x7F + 1)...(0x7FF) => {
+ std.debug.panic("emoji not implemented yet!", .{});
+ },
+ else => {
+ std.debug.panic("emoji not implemented yet!", .{});
+ },
+ }
+}
+
pub fn toUTF16Buf(in: string, out: []u16) usize {
var utf8Iterator = std.unicode.Utf8Iterator{ .bytes = in, .i = 0 };