mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
hm
This commit is contained in:
@@ -30,6 +30,7 @@ pub const UserDefines = std.StringHashMap(DefineData);
|
||||
|
||||
pub const DefineData = struct {
|
||||
value: js_ast.Expr.Data,
|
||||
valueless: bool = false,
|
||||
original_name: ?string = null,
|
||||
|
||||
// True if accessing this value is known to not have any side effects. For
|
||||
@@ -46,6 +47,10 @@ pub const DefineData = struct {
|
||||
// So we can create just one struct for it.
|
||||
pub const GlobalDefineData = DefineData{};
|
||||
|
||||
pub fn isUndefined(self: *const DefineData) bool {
|
||||
return self.valueless;
|
||||
}
|
||||
|
||||
pub fn merge(a: DefineData, b: DefineData) DefineData {
|
||||
return DefineData{
|
||||
.value = b.value,
|
||||
@@ -142,7 +147,7 @@ pub const Define = struct {
|
||||
dots: std.StringHashMap([]DotDefine),
|
||||
allocator: *std.mem.Allocator,
|
||||
|
||||
pub fn init(allocator: *std.mem.Allocator, user_defines: UserDefines) !*@This() {
|
||||
pub fn init(allocator: *std.mem.Allocator, _user_defines: ?UserDefines) !*@This() {
|
||||
var define = try allocator.create(Define);
|
||||
define.allocator = allocator;
|
||||
define.identifiers = std.StringHashMap(IdentifierDefine).init(allocator);
|
||||
@@ -155,7 +160,7 @@ pub const Define = struct {
|
||||
var ident_define = IdentifierDefine{
|
||||
.value = val,
|
||||
};
|
||||
var value_define = DefineData{ .value = val };
|
||||
var value_define = DefineData{ .value = val, .valueless = true };
|
||||
// Step 1. Load the globals into the hash tables
|
||||
for (GlobalDefinesKey) |global| {
|
||||
if (global.len == 1) {
|
||||
@@ -204,7 +209,7 @@ pub const Define = struct {
|
||||
|
||||
// Step 3. Load user data into hash tables
|
||||
// At this stage, user data has already been validated.
|
||||
if (user_defines.count() > 0) {
|
||||
if (_user_defines) |user_defines| {
|
||||
var iter = user_defines.iterator();
|
||||
while (iter.next()) |user_define| {
|
||||
// If it has a dot, then it's a DotDefine.
|
||||
|
||||
@@ -608,11 +608,11 @@ pub const Symbol = struct {
|
||||
};
|
||||
|
||||
pub fn isKindPrivate(kind: Symbol.Kind) bool {
|
||||
return kind >= Symbol.Kind.private_field and kind <= Symbol.Kind.private_static_get_set_pair;
|
||||
return @enumToInt(kind) >= @enumToInt(Symbol.Kind.private_field) and @enumToInt(kind) <= @enumToInt(Symbol.Kind.private_static_get_set_pair);
|
||||
}
|
||||
|
||||
pub fn isKindHoisted(kind: Symbol.Kind) bool {
|
||||
return kind == Symbol.Kind.hoisted or kind == Symbol.Kind.hoisted_function;
|
||||
return @enumToInt(kind) == @enumToInt(Symbol.Kind.hoisted) or @enumToInt(kind) == @enumToInt(Symbol.Kind.hoisted_function);
|
||||
}
|
||||
|
||||
pub fn isHoisted(self: *Symbol) bool {
|
||||
@@ -1222,6 +1222,14 @@ pub const Expr = struct {
|
||||
|
||||
pub const EFlags = enum { none, ts_decorator };
|
||||
|
||||
pub fn extractNumericValues(left: Expr.Data, right: Expr.Data) ?[2]f64 {
|
||||
if (!(@as(Expr.Tag, left) == .e_number and @as(Expr.Tag, right) == .e_number)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [2]f64{ left.e_number.value, right.e_number.value };
|
||||
}
|
||||
|
||||
pub fn isAnonymousNamed(e: *Expr) bool {
|
||||
switch (e.data) {
|
||||
.e_arrow => {
|
||||
@@ -2045,6 +2053,38 @@ pub const Expr = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn isBoolean(a: Expr) bool {
|
||||
switch (a.data) {
|
||||
.e_boolean => {
|
||||
return true;
|
||||
},
|
||||
|
||||
.e_if => |ex| {
|
||||
return isBoolean(ex.yes) and isBoolean(ex.no);
|
||||
},
|
||||
.e_unary => |ex| {
|
||||
return ex.op == .un_not or ex.op == .un_delete;
|
||||
},
|
||||
.e_binary => |ex| {
|
||||
switch (ex.op) {
|
||||
.bin_strict_eq, .bin_strict_ne, .bin_loose_eq, .bin_loose_ne, .bin_lt, .bin_gt, .bin_le, .bin_ge, .bin_instanceof, .bin_in => {
|
||||
return true;
|
||||
},
|
||||
.bin_logical_or => {
|
||||
return isBoolean(ex.left) and isBoolean(ex.right);
|
||||
},
|
||||
.bin_logical_and => {
|
||||
return isBoolean(ex.left) and isBoolean(ex.right);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn assign(a: Expr, b: Expr, allocator: *std.mem.Allocator) Expr {
|
||||
return alloc(allocator, E.Binary{
|
||||
.op = .bin_assign,
|
||||
@@ -2052,16 +2092,16 @@ pub const Expr = struct {
|
||||
.right = b,
|
||||
}, a.loc);
|
||||
}
|
||||
pub fn at(expr: *Expr, t: anytype, allocator: *std.mem.allocator) callconv(.Inline) Expr {
|
||||
return alloc(allocator, t, loc);
|
||||
pub fn at(expr: *Expr, t: anytype, allocator: *std.mem.Allocator) callconv(.Inline) Expr {
|
||||
return alloc(allocator, t, expr.loc);
|
||||
}
|
||||
|
||||
// Wraps the provided expression in the "!" prefix operator. The expression
|
||||
// will potentially be simplified to avoid generating unnecessary extra "!"
|
||||
// operators. For example, calling this with "!!x" will return "!x" instead
|
||||
// of returning "!!!x".
|
||||
pub fn not(expr: Expr, allocator: *std.mem.Allocator) Expr {
|
||||
return maybeSimplifyNot(&expr, allocator) orelse expr;
|
||||
pub fn not(expr: *Expr, allocator: *std.mem.Allocator) Expr {
|
||||
return maybeSimplifyNot(expr, allocator) orelse expr.*;
|
||||
}
|
||||
|
||||
// The given "expr" argument should be the operand of a "!" prefix operator
|
||||
@@ -2086,16 +2126,16 @@ pub const Expr = struct {
|
||||
.e_function,
|
||||
.e_arrow,
|
||||
.e_reg_exp,
|
||||
=> |b| {
|
||||
=> {
|
||||
return expr.at(E.Boolean{ .value = false }, allocator);
|
||||
},
|
||||
// "!!!a" => "!a"
|
||||
.e_unary => |un| {
|
||||
if (un.op == Op.Code.un_not and isBooleanValue(un.value)) {
|
||||
return un.value.*;
|
||||
if (un.op == Op.Code.un_not and isBoolean(un.value)) {
|
||||
return un.value;
|
||||
}
|
||||
},
|
||||
.e_binary => |*ex| {
|
||||
.e_binary => |ex| {
|
||||
// TODO: evaluate whether or not it is safe to do this mutation since it's modifying in-place.
|
||||
// Make sure that these transformations are all safe for special values.
|
||||
// For example, "!(a < b)" is not the same as "a >= b" if a and/or b are
|
||||
@@ -2105,20 +2145,20 @@ pub const Expr = struct {
|
||||
ex.op = .bin_loose_ne;
|
||||
return expr.*;
|
||||
},
|
||||
Op.Code.bin_op_loose_ne => {
|
||||
Op.Code.bin_loose_ne => {
|
||||
ex.op = .bin_loose_eq;
|
||||
return expr.*;
|
||||
},
|
||||
Op.Code.bin_op_strict_eq => {
|
||||
Op.Code.bin_strict_eq => {
|
||||
ex.op = .bin_strict_ne;
|
||||
return expr.*;
|
||||
},
|
||||
Op.Code.bin_op_strict_ne => {
|
||||
Op.Code.bin_strict_ne => {
|
||||
ex.op = .bin_strict_eq;
|
||||
return expr.*;
|
||||
},
|
||||
Op.Code.bin_op_comma => {
|
||||
ex.right = ex.right.not();
|
||||
Op.Code.bin_comma => {
|
||||
ex.right = ex.right.not(allocator);
|
||||
return expr.*;
|
||||
},
|
||||
else => {},
|
||||
|
||||
1449
src/js_parser.zig
1449
src/js_parser.zig
File diff suppressed because it is too large
Load Diff
12
src/main.zig
12
src/main.zig
@@ -9,6 +9,7 @@ const js_printer = @import("js_printer.zig");
|
||||
const js_ast = @import("js_ast.zig");
|
||||
const linker = @import("linker.zig");
|
||||
usingnamespace @import("ast/base.zig");
|
||||
usingnamespace @import("defines.zig");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
try alloc.setup(std.heap.page_allocator);
|
||||
@@ -31,6 +32,15 @@ pub fn main() anyerror!void {
|
||||
var log = logger.Log.init(alloc.dynamic);
|
||||
var source = logger.Source.initFile(opts.entry_point, alloc.dynamic);
|
||||
var ast: js_ast.Ast = undefined;
|
||||
var raw_defines = RawDefines.init(alloc.static);
|
||||
try raw_defines.put("process.env.NODE_ENV", "\"development\"");
|
||||
|
||||
var user_defines = try DefineData.from_input(raw_defines, &log, alloc.static);
|
||||
|
||||
var define = try Define.init(
|
||||
alloc.static,
|
||||
user_defines,
|
||||
);
|
||||
|
||||
switch (opts.loader) {
|
||||
.json => {
|
||||
@@ -47,7 +57,7 @@ pub fn main() anyerror!void {
|
||||
ast = js_ast.Ast.initTest(&([_]js_ast.Part{part}));
|
||||
},
|
||||
.jsx, .tsx, .ts, .js => {
|
||||
var parser = try js_parser.Parser.init(opts, &log, &source, alloc.dynamic);
|
||||
var parser = try js_parser.Parser.init(opts, &log, &source, define, alloc.dynamic);
|
||||
var res = try parser.parse();
|
||||
ast = res.ast;
|
||||
},
|
||||
|
||||
@@ -181,7 +181,7 @@ pub fn toUTF16Buf(in: string, out: []u16) usize {
|
||||
}
|
||||
}
|
||||
|
||||
return utf8Iterator.i;
|
||||
return i;
|
||||
}
|
||||
|
||||
pub fn toUTF16Alloc(in: string, allocator: *std.mem.Allocator) !JavascriptString {
|
||||
|
||||
Reference in New Issue
Block a user