const std = @import("std"); const logger = @import("logger.zig"); const js_lexer = @import("js_lexer.zig"); const importRecord = @import("import_record.zig"); const js_ast = @import("js_ast.zig"); const options = @import("options.zig"); const alloc = @import("alloc.zig"); const js_printer = @import("js_printer.zig"); const renamer = @import("renamer.zig"); const fs = @import("fs.zig"); usingnamespace @import("strings.zig"); usingnamespace @import("ast/base.zig"); usingnamespace js_ast.G; usingnamespace @import("defines.zig"); const ImportKind = importRecord.ImportKind; const BindingNodeIndex = js_ast.BindingNodeIndex; const StmtNodeIndex = js_ast.StmtNodeIndex; const ExprNodeIndex = js_ast.ExprNodeIndex; const ExprNodeList = js_ast.ExprNodeList; const StmtNodeList = js_ast.StmtNodeList; const BindingNodeList = js_ast.BindingNodeList; const assert = std.debug.assert; const LocRef = js_ast.LocRef; const S = js_ast.S; const B = js_ast.B; const G = js_ast.G; const T = js_lexer.T; const E = js_ast.E; const Stmt = js_ast.Stmt; const Expr = js_ast.Expr; const Binding = js_ast.Binding; const Symbol = js_ast.Symbol; const Level = js_ast.Op.Level; const Op = js_ast.Op; const Scope = js_ast.Scope; const locModuleScope = logger.Loc.Empty; pub fn ExpressionTransposer(comptime ctx: type, visitor: fn (ptr: *ctx, arg: Expr, state: anytype) Expr) type { return struct { context: *Context, pub fn init(c: *Context) @This() { return @This(){ .context = c, }; } pub fn maybeTransposeIf(self: *@This(), arg: Expr, state: anytype) Expr { switch (arg.data) { .e_if => |ex| { ex.yes = self.maybeTransposeIf(ex.yes, state); ex.no = self.maybeTransposeIf(ex.no, state); return arg; }, else => { return visitor(self.context, arg, state); }, } } pub const Context = ctx; }; } pub fn locAfterOp(e: E.Binary) logger.Loc { if (e.left.loc.start < e.right.loc.start) { return e.right.loc; } else { // handle the case when we have transposed the operands return e.left.loc; } } pub const ImportScanner = struct { stmts: []Stmt = &([_]Stmt{}), kept_import_equals: bool = false, removed_import_equals: bool = false, pub fn scan(p: *P, stmts: []Stmt) !ImportScanner { var scanner = ImportScanner{}; var stmts_end: usize = 0; for (stmts) |_stmt| { // zls needs the hint, it seems. const stmt: Stmt = _stmt; switch (stmt.data) { .s_import => |st| { var record: ImportRecord = p.import_records.items[st.import_record_index]; // The official TypeScript compiler always removes unused imported // symbols. However, we deliberately deviate from the official // TypeScript compiler's behavior doing this in a specific scenario: // we are not bundling, symbol renaming is off, and the tsconfig.json // "importsNotUsedAsValues" setting is present and is not set to // "remove". // // This exists to support the use case of compiling partial modules for // compile-to-JavaScript languages such as Svelte. These languages try // to reference imports in ways that are impossible for esbuild to know // about when esbuild is only given a partial module to compile. Here // is an example of some Svelte code that might use esbuild to convert // TypeScript to JavaScript: // // //
//

Hello {name}!

// //
// // Tools that use esbuild to compile TypeScript code inside a Svelte // file like this only give esbuild the contents of the