diff options
author | 2021-10-30 21:44:31 -0700 | |
---|---|---|
committer | 2021-10-30 21:44:31 -0700 | |
commit | 1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22 (patch) | |
tree | 58c1a80489471b4be14c3ee128e441ba2582992c | |
parent | cd5c740368811ce49eeabb5f72d7ac2fa7098843 (diff) | |
download | bun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.tar.gz bun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.tar.zst bun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.zip |
Fixes #34
-rw-r--r-- | src/js_lexer.zig | 66 | ||||
-rw-r--r-- | src/js_printer.zig | 19 |
2 files changed, 65 insertions, 20 deletions
diff --git a/src/js_lexer.zig b/src/js_lexer.zig index 5651c2175..8137c71db 100644 --- a/src/js_lexer.zig +++ b/src/js_lexer.zig @@ -295,17 +295,27 @@ pub fn NewLexer(comptime json_options: JSONOptions) type { // 1-3 digit octal var is_bad = false; var value: i64 = c2 - '0'; + var restore = iter; + + _ = iterator.next(&iter) or { + if (value == 0) { + try buf.append(0); + return; + } + + try lexer.syntaxError(); + return; + }; - _ = iterator.next(&iter) or return lexer.syntaxError(); const c3: CodePoint = iter.c; const width3 = iter.width; switch (c3) { '0'...'7' => { value = value * 8 + c3 - '0'; - iter.i += width3; - + restore = iter; _ = iterator.next(&iter) or return lexer.syntaxError(); + const c4 = iter.c; const width4 = iter.width; switch (c4) { @@ -313,20 +323,26 @@ pub fn NewLexer(comptime json_options: JSONOptions) type { const temp = value * 8 + c4 - '0'; if (temp < 256) { value = temp; - iter.i += width4; + } else { + iter = restore; } }, '8', '9' => { is_bad = true; }, - else => {}, + else => { + iter = restore; + }, } }, '8', '9' => { is_bad = true; }, - else => {}, + else => { + iter = restore; + }, } + iter.c = @intCast(i32, value); if (is_bad) { lexer.addRangeError( @@ -2658,12 +2674,13 @@ pub fn isIdentifierUTF16(text: []const u16) bool { } var i: usize = 0; - while (i < n) : (i += 1) { + while (i < n) { const is_start = i == 0; - var codepoint = @as(CodePoint, text[i]); - if (codepoint >= 0xD800 and codepoint <= 0xDBFF and i + 1 < n) { - const surrogate = @as(CodePoint, text[i + 1]); + i += 1; + + if (codepoint >= 0xD800 and codepoint <= 0xDBFF and i < n) { + const surrogate = @as(CodePoint, text[i]); if (surrogate >= 0xDC00 and surrogate <= 0xDFFF) { codepoint = (codepoint << 10) + surrogate + (0x10000 - (0xD800 << 10) - 0xDC00); i += 1; @@ -2755,6 +2772,35 @@ inline fn float64(num: anytype) f64 { return @intToFloat(f64, num); } +pub fn isLatin1Identifier(comptime Buffer: type, name: Buffer) bool { + if (name.len == 0) return false; + + switch (name[0]) { + 'a'...'z', + 'A'...'Z', + '$', + '_', + => {}, + else => return false, + } + + if (name.len > 0) { + for (name[1..]) |c| { + switch (c) { + '0'...'9', + 'a'...'z', + 'A'...'Z', + '$', + '_', + => {}, + else => return false, + } + } + } + + return true; +} + test "isIdentifier" { const expect = std.testing.expect; try expect(!isIdentifierStart(0x2029)); diff --git a/src/js_printer.zig b/src/js_printer.zig index 0551305f6..f6468966e 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -450,7 +450,7 @@ pub fn NewPrinter( p.printIdentifier(name); } pub fn printClauseAlias(p: *Printer, alias: string) void { - if (js_lexer.isIdentifier(alias)) { + if (p.canPrintIdentifier(alias)) { p.printSpaceBeforeIdentifier(); p.printIdentifier(alias); } else { @@ -938,20 +938,18 @@ pub fn NewPrinter( if (comptime is_json) return false; if (comptime ascii_only) { - return js_lexer.isIdentifier(name) and !strings.containsNonBmpCodePoint(name); + return js_lexer.isLatin1Identifier(string, name); } else { return js_lexer.isIdentifier(name); } } pub inline fn canPrintIdentifierUTF16(p: *Printer, name: []const u16) bool { - if (comptime is_json) return false; - return false; - // if (comptime ascii_only) { - // return js_lexer.isIdentifierUTF16(name) and !strings.containsNonBmpCodePointUTF16(name); - // } else { - // return js_lexer.isIdentifierUTF16(name); - // } + if (comptime ascii_only) { + return js_lexer.isLatin1Identifier([]const u16, name); + } else { + return js_lexer.isIdentifierUTF16(name); + } } pub fn printExpr(p: *Printer, expr: Expr, level: Level, _flags: ExprFlag) void { @@ -1948,7 +1946,7 @@ pub fn NewPrinter( // While each of those property keys are ASCII, a subset of ASCII is valid as the start of an identifier // "=" and ":" are not valid // So we need to check - if ((comptime !is_json) and js_lexer.isIdentifier(key.utf8)) { + if ((comptime !is_json) and p.canPrintIdentifier(key.utf8)) { p.print(key.utf8); } else { allow_shorthand = false; @@ -3831,6 +3829,7 @@ pub fn NewPrinter( if (c & ~@as(CodeUnitType, 0x03ff) == 0xd800 and i < n) { c = 0x10000 + (((c & 0x03ff) << 10) | (name[i] & 0x03ff)); + i += 1; } if ((comptime ascii_only) and c > last_ascii) { |