aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-04-14 03:44:41 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-04-14 03:44:41 -0700
commit6c69c2b36462100792bb3d1b23aba8afbee0253f (patch)
treef9ada0f7fed07ee23b62434d95629302e9689003
parentba057e50c360623b6aa7af39e5e74f26a5cd99e7 (diff)
downloadbun-6c69c2b36462100792bb3d1b23aba8afbee0253f.tar.gz
bun-6c69c2b36462100792bb3d1b23aba8afbee0253f.tar.zst
bun-6c69c2b36462100792bb3d1b23aba8afbee0253f.zip
Implement `@bun` annotation
-rw-r--r--src/bun.js/module_loader.zig20
-rw-r--r--src/bun.js/test/jest.zig2
-rw-r--r--src/bundler.zig28
-rw-r--r--src/bundler/bundle_v2.zig11
-rw-r--r--src/cache.zig4
-rw-r--r--src/js_ast.zig4
-rw-r--r--src/js_parser.zig22
-rw-r--r--src/runtime.zig2
8 files changed, 65 insertions, 28 deletions
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index 8a46b063a..85bc04f53 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -943,12 +943,12 @@ pub const ModuleLoader = struct {
.jsx = jsc_vm.bundler.options.jsx,
.virtual_source = virtual_source,
.hoist_bun_plugin = true,
+ .dont_bundle_twice = true,
.inject_jest_globals = jsc_vm.bundler.options.rewrite_jest_for_tests and
jsc_vm.main.len == path.text.len and
jsc_vm.main_hash == hash and
strings.eqlLong(jsc_vm.main, path.text, false),
};
-
if (is_node_override) {
if (NodeFallbackModules.contentsFromPath(specifier)) |code| {
const fallback_path = Fs.Path.initWithNamespace(specifier, "node");
@@ -1038,6 +1038,20 @@ pub const ModuleLoader = struct {
};
}
+ if (parse_result.already_bundled) {
+ return ResolvedSource{
+ .allocator = null,
+ .source_code = ZigString.init(try default_allocator.dupe(u8, parse_result.source.contents)),
+ .specifier = ZigString.init(specifier),
+ .source_url = ZigString.init(path.text),
+ // // TODO: change hash to a bitfield
+ // .hash = 1,
+
+ // having JSC own the memory causes crashes
+ .hash = 0,
+ };
+ }
+
const has_bun_plugin = parse_result.ast.bun_plugin.hoisted_stmts.items.len > 0;
if (has_bun_plugin) {
@@ -1596,9 +1610,9 @@ pub const ModuleLoader = struct {
opts.filepath_hash_for_hmr = 0;
opts.warn_about_unbundled_modules = false;
opts.macro_context = &jsc_vm.bundler.macro_context.?;
- const main_ast = (bundler.resolver.caches.js.parse(jsc_vm.allocator, opts, bundler.options.define, bundler.log, &jsc_vm.entry_point.source) catch null) orelse {
+ const main_ast = ((bundler.resolver.caches.js.parse(jsc_vm.allocator, opts, bundler.options.define, bundler.log, &jsc_vm.entry_point.source) catch null) orelse {
return error.ParseError;
- };
+ }).ast;
var parse_result = ParseResult{ .source = jsc_vm.entry_point.source, .ast = main_ast, .loader = .js, .input_fd = null };
var file_path = Fs.Path.init(bundler.fs.top_level_dir);
file_path.name.dir = bundler.fs.top_level_dir;
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index 197bba03f..3dcecab4c 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -610,7 +610,7 @@ pub const Snapshots = struct {
);
var parse_result = try parser.parse();
- var ast = if (parse_result.ok) parse_result.ast else return error.ParseError;
+ var ast = if (parse_result == .ast) parse_result.ast else return error.ParseError;
defer ast.deinit();
if (ast.exports_ref.isNull()) return;
diff --git a/src/bundler.zig b/src/bundler.zig
index 86a5779b8..629e377ae 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -120,6 +120,7 @@ pub const ParseResult = struct {
source: logger.Source,
loader: options.Loader,
ast: js_ast.Ast,
+ already_bundled: bool = false,
input_fd: ?StoredFileDescriptorType = null,
empty: bool = false,
pending_imports: _resolver.PendingResolution.List = .{},
@@ -1275,6 +1276,8 @@ pub const Bundler = struct {
replace_exports: runtime.Runtime.Features.ReplaceableExport.Map = .{},
hoist_bun_plugin: bool = false,
inject_jest_globals: bool = false,
+
+ dont_bundle_twice: bool = false,
};
pub fn parse(
@@ -1382,6 +1385,9 @@ pub const Bundler = struct {
opts.features.should_fold_typescript_constant_expressions = loader.isTypeScript() or platform.isBun();
opts.features.dynamic_require = platform.isBun();
+ // @bun annotation
+ opts.features.dont_bundle_twice = this_parse.dont_bundle_twice;
+
opts.can_import_from_bundle = bundler.options.node_modules_bundle != null;
opts.tree_shaking = bundler.options.tree_shaking;
@@ -1426,18 +1432,26 @@ pub const Bundler = struct {
opts.features.is_macro_runtime = platform == .bun_macro;
opts.features.replace_exports = this_parse.replace_exports;
- const value = (bundler.resolver.caches.js.parse(
+ return switch ((bundler.resolver.caches.js.parse(
allocator,
opts,
bundler.options.define,
bundler.log,
&source,
- ) catch null) orelse return null;
- return ParseResult{
- .ast = value,
- .source = source,
- .loader = loader,
- .input_fd = input_fd,
+ ) catch null) orelse return null) {
+ .ast => |value| ParseResult{
+ .ast = value,
+ .source = source,
+ .loader = loader,
+ .input_fd = input_fd,
+ },
+ .already_bundled => ParseResult{
+ .ast = undefined,
+ .already_bundled = true,
+ .source = source,
+ .loader = loader,
+ .input_fd = input_fd,
+ },
};
},
.json => {
diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig
index 1fa26bb8f..380f44a83 100644
--- a/src/bundler/bundle_v2.zig
+++ b/src/bundler/bundle_v2.zig
@@ -797,13 +797,16 @@ const ParseTask = struct {
) !js_ast.Ast {
switch (loader) {
.jsx, .tsx, .js, .ts => {
- return (try resolver.caches.js.parse(
+ return if (try resolver.caches.js.parse(
bundler.allocator,
opts,
bundler.options.define,
log,
&source,
- )) orelse return try getEmptyAST(log, bundler, opts, allocator, source);
+ )) |res|
+ res.ast
+ else
+ try getEmptyAST(log, bundler, opts, allocator, source);
},
.json => {
const root = (try resolver.caches.json.parseJSON(log, source, allocator)) orelse Expr.init(E.Object, E.Object{}, Logger.Loc.Empty);
@@ -4638,6 +4641,10 @@ const LinkerContext = struct {
}
}
+ if (chunk.entry_point.is_entry_point and ctx.c.graph.ast.items(.platform)[chunk.entry_point.source_index].isBun()) {
+ j.push("// @bun\n");
+ }
+
// TODO: banner
// TODO: directive
diff --git a/src/cache.zig b/src/cache.zig
index a5d73e0fd..cffeccadd 100644
--- a/src/cache.zig
+++ b/src/cache.zig
@@ -221,7 +221,7 @@ pub const JavaScript = struct {
defines: *Define,
log: *logger.Log,
source: *const logger.Source,
- ) anyerror!?js_ast.Ast {
+ ) anyerror!?js_ast.Result {
var temp_log = logger.Log.init(allocator);
var parser = js_parser.Parser.init(opts, &temp_log, source, defines, allocator) catch {
temp_log.appendToMaybeRecycled(log, source) catch {};
@@ -238,7 +238,7 @@ pub const JavaScript = struct {
};
temp_log.appendToMaybeRecycled(log, source) catch {};
- return if (result.ok) result.ast else null;
+ return result;
}
pub fn scan(
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 8ae239e2f..c0e4de6d9 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -5547,9 +5547,9 @@ pub const Part = struct {
}
};
-pub const Result = struct {
+pub const Result = union(enum) {
+ already_bundled: void,
ast: Ast,
- ok: bool = false,
};
pub const StmtOrExpr = union(enum) {
diff --git a/src/js_parser.zig b/src/js_parser.zig
index a6a6d3a1e..3ce9549d9 100644
--- a/src/js_parser.zig
+++ b/src/js_parser.zig
@@ -2759,6 +2759,7 @@ pub const Parser = struct {
p.should_fold_typescript_constant_expressions = this.options.features.should_fold_typescript_constant_expressions;
defer p.lexer.deinit();
var result: js_ast.Result = undefined;
+ _ = result;
try p.prepareForVisitPass();
var final_expr = expr;
@@ -2796,10 +2797,7 @@ pub const Parser = struct {
}
break :brk .none;
};
- result.ast = try p.toAST(parts, exports_kind, null);
- result.ok = true;
-
- return result;
+ return .{ .ast = try p.toAST(parts, exports_kind, null) };
}
pub fn parse(self: *Parser) !js_ast.Result {
@@ -2834,6 +2832,7 @@ pub const Parser = struct {
p.should_fold_typescript_constant_expressions = self.options.features.should_fold_typescript_constant_expressions;
defer p.lexer.deinit();
var result: js_ast.Result = undefined;
+ _ = result;
// defer {
// if (p.allocated_names_pool) |pool| {
@@ -2850,6 +2849,12 @@ pub const Parser = struct {
try p.lexer.next();
}
+ if (p.lexer.bun_pragma and p.options.features.dont_bundle_twice) {
+ return js_ast.Result{
+ .already_bundled = {},
+ };
+ }
+
// Parse the file in the first pass, but do not bind symbols
var opts = ParseStatementOptions{ .is_module_scope = true };
@@ -3098,7 +3103,6 @@ pub const Parser = struct {
left.data.e_dot.target.data.e_identifier.ref.eql(p.module_ref))
{
return js_ast.Result{
- .ok = true,
.ast = js_ast.Ast{
.allocator = p.allocator,
.import_records = ImportRecord.List.init(p.import_records.items),
@@ -3115,7 +3119,6 @@ pub const Parser = struct {
.s_export_star => |star| {
if (star.alias == null) {
return js_ast.Result{
- .ok = true,
.ast = .{
.allocator = p.allocator,
.import_records = ImportRecord.List.init(p.import_records.items),
@@ -4021,10 +4024,7 @@ pub const Parser = struct {
// Pop the module scope to apply the "ContainsDirectEval" rules
// p.popScope();
- result.ast = try p.toAST(parts_slice, exports_kind, wrapper_expr);
- result.ok = true;
-
- return result;
+ return js_ast.Result{ .ast = try p.toAST(parts_slice, exports_kind, wrapper_expr) };
}
pub fn init(_options: Options, log: *logger.Log, source: *const logger.Source, define: *Define, allocator: Allocator) !Parser {
@@ -20969,5 +20969,5 @@ pub fn newLazyExportAST(
temp_log.appendToMaybeRecycled(log_to_copy_into, source) catch {};
result.ast.has_lazy_export = true;
- return if (result.ok) result.ast else null;
+ return result.ast;
}
diff --git a/src/runtime.zig b/src/runtime.zig
index 953034ab8..36aff3ab6 100644
--- a/src/runtime.zig
+++ b/src/runtime.zig
@@ -322,6 +322,8 @@ pub const Runtime = struct {
hoist_bun_plugin: bool = false,
+ dont_bundle_twice: bool = false,
+
pub const ReplaceableExport = union(enum) {
delete: void,
replace: JSAst.Expr,