aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-30 21:44:31 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-30 21:44:31 -0700
commit1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22 (patch)
tree58c1a80489471b4be14c3ee128e441ba2582992c
parentcd5c740368811ce49eeabb5f72d7ac2fa7098843 (diff)
downloadbun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.tar.gz
bun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.tar.zst
bun-1876c0e11a5a3498dc5fb86a2e8dc5316a1a0e22.zip
Fixes #34
-rw-r--r--src/js_lexer.zig66
-rw-r--r--src/js_printer.zig19
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) {