mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
try
This commit is contained in:
@@ -26,25 +26,27 @@ pub fn Parse(
|
||||
pub const parseTypeScriptImportEqualsStmt = @import("./parseTypescript.zig").ParseTypescript(parser_feature__typescript, parser_feature__jsx, parser_feature__scan_only).parseTypeScriptImportEqualsStmt;
|
||||
pub const parseTypescriptEnumStmt = @import("./parseTypescript.zig").ParseTypescript(parser_feature__typescript, parser_feature__jsx, parser_feature__scan_only).parseTypescriptEnumStmt;
|
||||
|
||||
pub inline fn parseExprOrBindings(p: *P, level: Level, errors: ?*DeferredErrors) anyerror!Expr {
|
||||
return try p.parseExprCommon(level, errors, Expr.EFlags.none);
|
||||
pub inline fn parseExprOrBindings(p: *P, level: Level, errors: ?*DeferredErrors, expr: *Expr) anyerror!void {
|
||||
return p.parseExprCommon(level, errors, Expr.EFlags.none, expr);
|
||||
}
|
||||
|
||||
pub inline fn parseExpr(p: *P, level: Level) anyerror!Expr {
|
||||
return try p.parseExprCommon(level, null, Expr.EFlags.none);
|
||||
var expr: Expr = undefined;
|
||||
try p.parseExprCommon(level, null, Expr.EFlags.none, &expr);
|
||||
return expr;
|
||||
}
|
||||
|
||||
pub inline fn parseExprWithFlags(p: *P, level: Level, flags: Expr.EFlags) anyerror!Expr {
|
||||
return try p.parseExprCommon(level, null, flags);
|
||||
pub inline fn parseExprWithFlags(p: *P, level: Level, flags: Expr.EFlags, expr: *Expr) anyerror!void {
|
||||
return p.parseExprCommon(level, null, flags, expr);
|
||||
}
|
||||
|
||||
pub fn parseExprCommon(p: *P, level: Level, errors: ?*DeferredErrors, flags: Expr.EFlags) anyerror!Expr {
|
||||
pub fn parseExprCommon(p: *P, level: Level, errors: ?*DeferredErrors, flags: Expr.EFlags, expr: *Expr) anyerror!void {
|
||||
if (!p.stack_check.isSafeToRecurse()) {
|
||||
try bun.throwStackOverflow();
|
||||
}
|
||||
|
||||
const had_pure_comment_before = p.lexer.has_pure_comment_before and !p.options.ignore_dce_annotations;
|
||||
var expr = try p.parsePrefix(level, errors, flags);
|
||||
expr.* = try p.parsePrefix(level, errors, flags);
|
||||
|
||||
// There is no formal spec for "__PURE__" comments but from reverse-
|
||||
// engineering, it looks like they apply to the next CallExpression or
|
||||
@@ -52,7 +54,7 @@ pub fn Parse(
|
||||
// to the expression "a().b()".
|
||||
|
||||
if (had_pure_comment_before and level.lt(.call)) {
|
||||
expr = try p.parseSuffix(expr, @as(Level, @enumFromInt(@intFromEnum(Level.call) - 1)), errors, flags);
|
||||
try p.parseSuffix(expr, @as(Level, @enumFromInt(@intFromEnum(Level.call) - 1)), errors, flags);
|
||||
switch (expr.data) {
|
||||
.e_call => |ex| {
|
||||
ex.can_be_unwrapped_if_unused = .if_unused;
|
||||
@@ -64,7 +66,7 @@ pub fn Parse(
|
||||
}
|
||||
}
|
||||
|
||||
return try p.parseSuffix(expr, level, errors, flags);
|
||||
try p.parseSuffix(expr, level, errors, flags);
|
||||
}
|
||||
|
||||
pub fn parseYieldExpr(p: *P, loc: logger.Loc) !ExprNodeIndex {
|
||||
@@ -343,10 +345,13 @@ pub fn Parse(
|
||||
// We don't know yet whether these are arguments or expressions, so parse
|
||||
p.latest_arrow_arg_loc = p.lexer.loc();
|
||||
|
||||
var item = try p.parseExprOrBindings(.comma, &errors);
|
||||
try items_list.ensureUnusedCapacity(1);
|
||||
const item: *Expr = &items_list.unusedCapacitySlice()[0];
|
||||
try p.parseExprOrBindings(.comma, &errors, item);
|
||||
items_list.items.len += 1;
|
||||
|
||||
if (is_spread) {
|
||||
item = p.newExpr(E.Spread{ .value = item }, loc);
|
||||
item.* = p.newExpr(E.Spread{ .value = item.* }, loc);
|
||||
}
|
||||
|
||||
// Skip over types
|
||||
@@ -359,11 +364,9 @@ pub fn Parse(
|
||||
// There may be a "=" after the type (but not after an "as" cast)
|
||||
if (is_typescript_enabled and p.lexer.token == .t_equals and !p.forbid_suffix_after_as_loc.eql(p.lexer.loc())) {
|
||||
try p.lexer.next();
|
||||
item = Expr.assign(item, try p.parseExpr(.comma));
|
||||
item.* = Expr.assign(item.*, try p.parseExpr(.comma));
|
||||
}
|
||||
|
||||
items_list.append(item) catch unreachable;
|
||||
|
||||
if (p.lexer.token != .t_comma) {
|
||||
break;
|
||||
}
|
||||
@@ -675,7 +678,7 @@ pub fn Parse(
|
||||
try p.lexer.next();
|
||||
|
||||
const raw2 = p.lexer.raw();
|
||||
const value = if (p.lexer.token == .t_identifier and strings.eqlComptime(raw2, "using")) value: {
|
||||
var value = if (p.lexer.token == .t_identifier and strings.eqlComptime(raw2, "using")) value: {
|
||||
// const using_loc = p.saveExprCommentsHere();
|
||||
const using_range = p.lexer.range();
|
||||
try p.lexer.next();
|
||||
@@ -711,13 +714,15 @@ pub fn Parse(
|
||||
if (p.lexer.token == .t_asterisk_asterisk) {
|
||||
try p.lexer.unexpected();
|
||||
}
|
||||
const expr = p.newExpr(
|
||||
E.Await{ .value = try p.parseSuffix(value, .prefix, null, .none) },
|
||||
try p.parseSuffix(&value, .prefix, null, .none);
|
||||
var expr = p.newExpr(
|
||||
E.Await{ .value = value },
|
||||
token_range.loc,
|
||||
);
|
||||
try p.parseSuffix(&expr, .lowest, null, .none);
|
||||
return ExprOrLetStmt{
|
||||
.stmt_or_expr = js_ast.StmtOrExpr{
|
||||
.expr = try p.parseSuffix(expr, .lowest, null, .none),
|
||||
.expr = expr,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
@@ -730,12 +735,13 @@ pub fn Parse(
|
||||
|
||||
// Parse the remainder of this expression that starts with an identifier
|
||||
const ref = try p.storeNameInRef(raw);
|
||||
const expr = p.newExpr(E.Identifier{ .ref = ref }, token_range.loc);
|
||||
return ExprOrLetStmt{
|
||||
var result = ExprOrLetStmt{
|
||||
.stmt_or_expr = js_ast.StmtOrExpr{
|
||||
.expr = try p.parseSuffix(expr, .lowest, null, .none),
|
||||
.expr = p.newExpr(E.Identifier{ .ref = ref }, token_range.loc),
|
||||
},
|
||||
};
|
||||
try p.parseSuffix(&result.stmt_or_expr.expr, .lowest, null, .none);
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn parseBinding(p: *P, comptime opts: ParseBindingOptions) anyerror!Binding {
|
||||
|
||||
@@ -381,8 +381,14 @@ pub fn ParsePrefix(
|
||||
return p.newExpr(E.NewTarget{ .range = range }, loc);
|
||||
}
|
||||
|
||||
const target = try p.parseExprWithFlags(.member, flags);
|
||||
var args = ExprNodeList{};
|
||||
// This wil become the new expr
|
||||
var new = p.newExpr(E.New{
|
||||
.target = undefined,
|
||||
.args = undefined,
|
||||
.close_parens_loc = undefined,
|
||||
}, loc);
|
||||
|
||||
try p.parseExprWithFlags(.member, flags, &new.data.e_new.target);
|
||||
|
||||
if (comptime is_typescript_enabled) {
|
||||
// Skip over TypeScript type arguments here if there are any
|
||||
@@ -391,18 +397,15 @@ pub fn ParsePrefix(
|
||||
}
|
||||
}
|
||||
|
||||
var close_parens_loc = logger.Loc.Empty;
|
||||
if (p.lexer.token == .t_open_paren) {
|
||||
const call_args = try p.parseCallArgs();
|
||||
args = call_args.list;
|
||||
close_parens_loc = call_args.loc;
|
||||
new.data.e_new.args = call_args.list;
|
||||
new.data.e_new.close_parens_loc = call_args.loc;
|
||||
} else {
|
||||
new.data.e_new.close_parens_loc = .Empty;
|
||||
}
|
||||
|
||||
return p.newExpr(E.New{
|
||||
.target = target,
|
||||
.args = args,
|
||||
.close_parens_loc = close_parens_loc,
|
||||
}, loc);
|
||||
return new;
|
||||
},
|
||||
.t_open_bracket => {
|
||||
try p.lexer.next();
|
||||
@@ -426,9 +429,11 @@ pub fn ParsePrefix(
|
||||
|
||||
const dots_loc = p.lexer.loc();
|
||||
try p.lexer.next();
|
||||
items.append(
|
||||
p.newExpr(E.Spread{ .value = try p.parseExprOrBindings(.comma, &self_errors) }, dots_loc),
|
||||
) catch unreachable;
|
||||
try items.ensureUnusedCapacity(1);
|
||||
const spread_expr: *Expr = &items.unusedCapacitySlice()[0];
|
||||
spread_expr.* = p.newExpr(E.Spread{ .value = undefined }, dots_loc);
|
||||
try p.parseExprOrBindings(.comma, &self_errors, &spread_expr.data.e_spread.value);
|
||||
items.items.len += 1;
|
||||
|
||||
// Commas are not allowed here when destructuring
|
||||
if (p.lexer.token == .t_comma) {
|
||||
@@ -436,9 +441,10 @@ pub fn ParsePrefix(
|
||||
}
|
||||
},
|
||||
else => {
|
||||
items.append(
|
||||
try p.parseExprOrBindings(.comma, &self_errors),
|
||||
) catch unreachable;
|
||||
try items.ensureUnusedCapacity(1);
|
||||
const item: *Expr = &items.unusedCapacitySlice()[0];
|
||||
try p.parseExprOrBindings(.comma, &self_errors, item);
|
||||
items.items.len += 1;
|
||||
},
|
||||
}
|
||||
|
||||
@@ -496,7 +502,19 @@ pub fn ParsePrefix(
|
||||
while (p.lexer.token != .t_close_brace) {
|
||||
if (p.lexer.token == .t_dot_dot_dot) {
|
||||
try p.lexer.next();
|
||||
properties.append(G.Property{ .kind = .spread, .value = try p.parseExpr(.comma) }) catch unreachable;
|
||||
try properties.ensureUnusedCapacity(1);
|
||||
const property: *G.Property = &properties.unusedCapacitySlice()[0];
|
||||
property.* = .{
|
||||
.kind = .spread,
|
||||
.value = Expr.empty,
|
||||
};
|
||||
|
||||
try p.parseExprOrBindings(
|
||||
.comma,
|
||||
&self_errors,
|
||||
&(property.value.?),
|
||||
);
|
||||
properties.items.len += 1;
|
||||
|
||||
// Commas are not allowed here when destructuring
|
||||
if (p.lexer.token == .t_comma) {
|
||||
|
||||
@@ -508,16 +508,17 @@ pub fn ParseProperty(
|
||||
|
||||
// Parse an object key/value pair
|
||||
try p.lexer.expect(.t_colon);
|
||||
const value = try p.parseExprOrBindings(.comma, errors);
|
||||
|
||||
return G.Property{
|
||||
var property: G.Property = .{
|
||||
.kind = kind,
|
||||
.flags = Flags.Property.init(.{
|
||||
.is_computed = is_computed,
|
||||
}),
|
||||
.key = key,
|
||||
.value = value,
|
||||
.value = Expr{ .data = .e_missing, .loc = .{} },
|
||||
};
|
||||
|
||||
try p.parseExprOrBindings(.comma, errors, &property.value.?);
|
||||
return property;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -185,8 +185,8 @@ pub fn ParseStmt(
|
||||
|
||||
const defaultName = try createDefaultName(p, loc);
|
||||
|
||||
const prefix_expr = try p.parseAsyncPrefixExpr(async_range, Level.comma);
|
||||
const expr = try p.parseSuffix(prefix_expr, Level.comma, null, Expr.EFlags.none);
|
||||
var expr = try p.parseAsyncPrefixExpr(async_range, Level.comma);
|
||||
try p.parseSuffix(&expr, Level.comma, null, Expr.EFlags.none);
|
||||
try p.lexer.expectOrInsertSemicolon();
|
||||
const value = js_ast.StmtOrExpr{ .expr = expr };
|
||||
p.has_export_default = true;
|
||||
@@ -926,7 +926,8 @@ pub fn ParseStmt(
|
||||
// "import.meta"
|
||||
.t_open_paren, .t_dot => {
|
||||
p.esm_import_keyword = previous_import_keyword; // this wasn't an esm import statement after all
|
||||
const expr = try p.parseSuffix(try p.parseImportExpr(loc, .lowest), .lowest, null, Expr.EFlags.none);
|
||||
var expr = try p.parseImportExpr(loc, .lowest);
|
||||
try p.parseSuffix(&expr, .lowest, null, Expr.EFlags.none);
|
||||
try p.lexer.expectOrInsertSemicolon();
|
||||
return p.s(S.SExpr{
|
||||
.value = expr,
|
||||
@@ -1164,7 +1165,8 @@ pub fn ParseStmt(
|
||||
return try p.parseFnStmt(async_range.loc, opts, async_range);
|
||||
}
|
||||
|
||||
expr = try p.parseSuffix(try p.parseAsyncPrefixExpr(async_range, .lowest), .lowest, null, Expr.EFlags.none);
|
||||
expr = try p.parseAsyncPrefixExpr(async_range, .lowest);
|
||||
try p.parseSuffix(&expr, .lowest, null, Expr.EFlags.none);
|
||||
} else {
|
||||
const exprOrLet = try p.parseExprOrLetStmt(opts);
|
||||
switch (exprOrLet.stmt_or_expr) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,9 @@ pub fn ParseTypescript(
|
||||
// }
|
||||
//
|
||||
// This matches the behavior of the TypeScript compiler.
|
||||
try decorators.append(try p.parseExprWithFlags(.new, Expr.EFlags.ts_decorator));
|
||||
try decorators.ensureUnusedCapacity(1);
|
||||
try p.parseExprWithFlags(.new, Expr.EFlags.ts_decorator, &decorators.unusedCapacitySlice()[0]);
|
||||
decorators.items.len += 1;
|
||||
}
|
||||
|
||||
return decorators.items;
|
||||
|
||||
Reference in New Issue
Block a user