aboutsummaryrefslogtreecommitdiff
path: root/src/js_parser/js_parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/js_parser/js_parser.zig')
-rw-r--r--src/js_parser/js_parser.zig80
1 files changed, 65 insertions, 15 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 7c8b25019..8fed3f736 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1305,13 +1305,43 @@ pub const Parser = struct {
const jsx_factory_symbol: Symbol = p.symbols.items[p.jsx_factory_ref.inner_index];
if (jsx_symbol.use_count_estimate > 0 or jsx_fragment_symbol.use_count_estimate > 0 or jsx_factory_symbol.use_count_estimate > 0) {
- var jsx_imports = [_]string{ p.options.jsx.jsx, p.options.jsx.fragment, p.options.jsx.factory };
+ var jsx_imports = [_]string{ "", "", "" };
var symbols = StringRefMap.init(p.allocator);
defer symbols.deinit();
- try symbols.put(p.options.jsx.jsx, p.jsx_runtime_ref);
- try symbols.put(p.options.jsx.fragment, p.jsx_fragment_ref);
- try symbols.put(p.options.jsx.factory, p.jsx_factory_ref);
- try p.generateImportStmt(p.options.jsx.import_source, &jsx_imports, &parts, symbols);
+ var i: usize = 0;
+ var additional_stmt: ?Stmt = null;
+ if (jsx_factory_symbol.use_count_estimate > 0) {
+ jsx_imports[i] = p.options.jsx.factory;
+ try symbols.put(p.options.jsx.factory, p.jsx_factory_ref);
+ i += 1;
+ }
+
+ if (jsx_symbol.use_count_estimate > 0) {
+ jsx_imports[i] = p.options.jsx.jsx;
+ i += 1;
+ try symbols.put(p.options.jsx.jsx, p.jsx_runtime_ref);
+ // While we are here, add the __jsxFilename declaration
+ }
+
+ if (p.options.jsx.development) {
+ const jsx_filename_symbol = p.symbols.items[p.jsx_filename_ref.inner_index];
+ if (jsx_filename_symbol.use_count_estimate > 0) {
+ var decls = try p.allocator.alloc(G.Decl, 1);
+ var filename_str = try strings.toUTF16Alloc(p.source.path.pretty, p.allocator);
+ decls[0] = G.Decl{ .binding = p.b(B.Identifier{ .ref = p.jsx_filename_ref }, logger.Loc{}), .value = p.e(E.String{ .value = filename_str }, logger.Loc{}) };
+ additional_stmt = p.s(S.Local{ .kind = .k_var, .decls = decls }, logger.Loc{});
+ try symbols.put(Prefill.Runtime.JSXFilename, p.jsx_filename_ref);
+ }
+ }
+
+ if (jsx_fragment_symbol.use_count_estimate > 0) {
+ jsx_imports[i] = p.options.jsx.fragment;
+
+ try symbols.put(p.options.jsx.fragment, p.jsx_fragment_ref);
+ i += 1;
+ }
+
+ try p.generateImportStmt(p.options.jsx.import_source, jsx_imports[0..i], &before, symbols, additional_stmt);
}
}
@@ -1480,7 +1510,7 @@ pub const Prefill = struct {
pub var ColumnNumber = Expr.Data{ .e_string = &Prefill.String.ColumnNumber };
};
pub const Runtime = struct {
- pub var JSXFilename = "JSX_fIlEnAmE";
+ pub var JSXFilename = "__jsxFilename";
pub var JSXDevelopmentImportName = "jsxDEV";
pub var JSXImportName = "jsx";
};
@@ -1573,6 +1603,8 @@ pub const P = struct {
jsx_factory_ref: js_ast.Ref = Ref.None,
jsx_fragment_ref: js_ast.Ref = Ref.None,
+ jsx_source_list_ref: js_ast.Ref = Ref.None,
+
// Imports (both ES6 and CommonJS) are tracked at the top level
import_records: List(ImportRecord),
import_records_for_current_part: List(u32),
@@ -2093,19 +2125,19 @@ pub const P = struct {
return p.e(ident, loc);
}
- pub fn generateImportStmt(p: *P, import_path: string, imports: []string, parts: *List(js_ast.Part), symbols: StringRefMap) !void {
- const import_record_i = p.addImportRecord(.stmt, logger.Loc.Empty, import_path);
+ pub fn generateImportStmt(p: *P, import_path: string, imports: []string, parts: *List(js_ast.Part), symbols: StringRefMap, additional_stmt: ?Stmt) !void {
+ const import_record_i = p.addImportRecordByRange(.stmt, logger.Range.None, import_path);
var import_record = p.import_records.items[import_record_i];
var import_path_identifier = try import_record.path.name.nonUniqueNameString(p.allocator);
var namespace_identifier = try p.allocator.alloc(u8, import_path_identifier.len + "import_".len);
var clause_items = try p.allocator.alloc(js_ast.ClauseItem, imports.len);
- var stmts = try p.allocator.alloc(Stmt, 1);
+ var stmts = try p.allocator.alloc(Stmt, 1 + if (additional_stmt != null) @as(usize, 1) else @as(usize, 0));
var declared_symbols = try p.allocator.alloc(js_ast.DeclaredSymbol, imports.len);
std.mem.copy(u8, namespace_identifier[0.."import_".len], "import_");
std.mem.copy(
u8,
- namespace_identifier["import_".len..import_path_identifier.len],
- import_path_identifier,
+ namespace_identifier["import_".len..namespace_identifier.len],
+ import_path_identifier[0..import_path_identifier.len],
);
const namespace_ref = try p.newSymbol(.other, namespace_identifier);
@@ -2129,13 +2161,21 @@ pub const P = struct {
.items = clause_items,
.import_record_index = import_record_i,
}, logger.Loc{});
+ if (additional_stmt) |add| {
+ stmts[1] = add;
+ }
var import_records = try p.allocator.alloc(@TypeOf(import_record_i), 1);
import_records[0] = import_record_i;
// Append a single import to the end of the file (ES6 imports are hoisted
// so we don't need to worry about where the import statement goes)
- parts.append(js_ast.Part{ .stmts = stmts, .declared_symbols = declared_symbols, .import_record_indices = import_records }) catch unreachable;
+ parts.append(js_ast.Part{
+ .stmts = stmts,
+ .declared_symbols = declared_symbols,
+ .import_record_indices = import_records,
+ .symbol_uses = SymbolUseMap.init(p.allocator),
+ }) catch unreachable;
}
pub fn prepareForVisitPass(p: *P) !void {
@@ -5136,10 +5176,14 @@ pub const P = struct {
}
pub fn addImportRecord(p: *P, kind: ImportKind, loc: logger.Loc, name: string) u32 {
+ return p.addImportRecordByRange(kind, p.source.rangeOfString(loc), name);
+ }
+
+ pub fn addImportRecordByRange(p: *P, kind: ImportKind, range: logger.Range, name: string) u32 {
var index = p.import_records.items.len;
const record = ImportRecord{
.kind = kind,
- .range = p.source.rangeOfString(loc),
+ .range = range,
.path = fs.Path.init(name),
};
p.import_records.append(record) catch unreachable;
@@ -7497,7 +7541,13 @@ pub const P = struct {
p.lexer.expected(.t_greater_than);
}
- return p.e(E.JSXElement{ .tag = end_tag.data.asExpr(), .children = children.toOwnedSlice() }, loc);
+ return p.e(E.JSXElement{
+ .tag = end_tag.data.asExpr(),
+ .children = children.toOwnedSlice(),
+ .properties = properties,
+ .key = key_prop,
+ .flags = flags,
+ }, loc);
},
else => {
p.lexer.unexpected();
@@ -8849,7 +8899,7 @@ pub const P = struct {
exprs[1] = p.e(E.String{
.value = p.lexer.stringToUTF16(name),
}, _value.loc);
- var value = p.callRuntime(_value.loc, "__name", exprs);
+ var value = p.callRuntime(_value.loc, "ℹ", exprs);
// Make sure tree shaking removes this if the function is never used
value.data.e_call.can_be_unwrapped_if_unused = true;