Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/js_parser/p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ pub struct P<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> {
pub(crate) macro_call_count: MacroCallCountType,

pub(crate) hoisted_ref_for_sloppy_mode_block_fn: RefRefMap,
/// Sloppy block-level functions with no Annex B `var`: a lexical binding of the same name is in its way.
pub(crate) sloppy_mode_block_fn_without_var: RefMap,

// Used for forcing CommonJS
pub(crate) has_with_scope: bool,
Expand Down Expand Up @@ -3421,6 +3423,17 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
self.options.bundle || self.options.features.minify_identifiers
}

/// Whether a block-level function becomes a `let`. Otherwise it stays a declaration for the engine's Annex B.
pub(crate) fn lowers_block_level_function(&self, name: Ref) -> bool {
// `hoist_symbols` makes the `var` twin of a sloppy function only for a renamer.
self.will_use_renamer()
// A function-level "use strict" is not printed, so strict code can run as sloppy text.
|| self.is_strict_mode()
// The REPL wraps each input in a function, which would own the `var` of a top-level block.
|| (self.options.repl_mode && self.fn_or_arrow_data_visit.is_outside_fn_or_arrow)
Comment thread
robobun marked this conversation as resolved.
Resolved
|| self.sloppy_mode_block_fn_without_var.contains_key(&name)
Comment thread
robobun marked this conversation as resolved.
Resolved
Comment thread
robobun marked this conversation as resolved.
Resolved
}

fn hoist_symbols(&mut self, mut scope: js_ast::StoreRef<js_ast::Scope>) {
// This runs before the visit pass, so it walks the scope tree at the full
// nesting depth the parser allowed; deep trees must error here instead of
Expand Down Expand Up @@ -3654,6 +3667,11 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
.hoisted_ref_for_sloppy_mode_block_fn
.remove(&original_member_ref);
}
} else if self.symbols[symbol_idx].kind
== js_ast::symbol::Kind::HoistedFunction
{
self.sloppy_mode_block_fn_without_var
.insert(original_member_ref, ());
}
continue 'next_member;
}
Expand Down Expand Up @@ -9730,6 +9748,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
has_classic_runtime_warned: false,
macro_call_count: 0,
hoisted_ref_for_sloppy_mode_block_fn: Default::default(),
sloppy_mode_block_fn_without_var: Default::default(),
has_with_scope: false,
has_top_level_function_merged_with_var: false,
is_file_considered_to_have_esm_exports: false,
Expand Down
1 change: 1 addition & 0 deletions src/js_parser/visit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,7 @@ impl<'a, const TYPESCRIPT: bool, const SCAN_ONLY: bool> P<'a, TYPESCRIPT, SCAN_O
&& p.symbols[data.func.name.unwrap().ref_.inner_index() as usize]
.kind
== SymbolKind::HoistedFunction
&& p.lowers_block_level_function(data.func.name.unwrap().ref_)
Comment thread
robobun marked this conversation as resolved.
Resolved
{
break 'list_getter &mut before;
}
Expand Down
3 changes: 2 additions & 1 deletion src/jsc/RuntimeTranspilerCache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ bun_core::declare_scope!(cache, visible);
/// Version 42: The body of a class with lowered class decorators names the class by the
/// binding that holds what the decorators return.
/// Version 43: A `bun:` specifier that names no builtin is printed as it is written.
const EXPECTED_VERSION: u32 = 43;
/// Version 44: A block-level function in sloppy code stays a declaration instead of becoming a `let`.
const EXPECTED_VERSION: u32 = 44;

/// Source files smaller than this are not written to / read from the on-disk
/// transpiler cache. Originally 50 KiB, which excluded almost every file in a
Expand Down
Loading
Loading