aboutsummaryrefslogtreecommitdiff
path: root/src/js_parser/js_parser.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-05 19:15:25 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-05 19:33:25 -0800
commit093807391a9563ad36c2b04a286da23d09fad835 (patch)
tree5485bda684d4f04b6a5af9a12f509fd47e906be1 /src/js_parser/js_parser.zig
parent18c923596a5b6480fa5a841bd0a6adfdb365b831 (diff)
downloadbun-093807391a9563ad36c2b04a286da23d09fad835.tar.gz
bun-093807391a9563ad36c2b04a286da23d09fad835.tar.zst
bun-093807391a9563ad36c2b04a286da23d09fad835.zip
[JS Parser] dot property shorthand for JSX
This is a non-standard backwards-compatible feature that I suspect other tooling will soon adopt (and expect to help other tooling adopt it) ```jsx var hello = {hi: 'yo'}; export const Foo = () => <Bar {hello.hi} /> ``` Desugars into: ```jsx var hello = {hi: 'yo'}; export const Foo = () => <Bar hi={hello.hi} /> ``` This works with defines and macros too. ```jsx export const Foo = () => <Bar {process.env.NODE_ENV} /> ``` ```jsx export const Foo = () => <Bar NODE_ENV="development" /> ```
Diffstat (limited to '')
-rw-r--r--src/js_parser/js_parser.zig37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index b299b4498..afe429e9e 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -11356,16 +11356,35 @@ fn NewParser_(
// ->
// <div foo={foo} />
T.t_identifier => {
- const name = p.lexer.identifier;
- if (strings.eqlComptime(name, "let")) {
- p.lexer.addError(p.source, p.lexer.loc(), "\"let\" is not allowed with JSX prop punning") catch unreachable;
- }
- const key = p.e(E.String{ .utf8 = name }, p.lexer.loc());
- const ref = p.storeNameInRef(name) catch unreachable;
- const value = p.e(E.Identifier{ .ref = ref }, key.loc);
- try p.lexer.next();
+ // we need to figure out what the key they mean is
+ // to do that, we must determine the key name
+ const expr = try p.parseExpr(Level.lowest);
+
+ const key = brk: {
+ switch (expr.data) {
+ .e_import_identifier => |ident| {
+ break :brk p.e(E.String{ .utf8 = p.loadNameFromRef(ident.ref) }, expr.loc);
+ },
+ .e_identifier => |ident| {
+ break :brk p.e(E.String{ .utf8 = p.loadNameFromRef(ident.ref) }, expr.loc);
+ },
+ .e_dot => |dot| {
+ break :brk p.e(E.String{ .utf8 = dot.name }, dot.name_loc);
+ },
+ .e_index => |index| {
+ if (index.index.data == .e_string) {
+ break :brk index.index;
+ }
+ },
+ else => {},
+ }
+
+ // If we get here, it's invalid
+ try p.log.addError(p.source, expr.loc, "Invalid JSX prop shorthand, must be identifier, dot or string");
+ return error.SyntaxError;
+ };
- try props.append(G.Property{ .value = value, .key = key, .kind = .normal });
+ try props.append(G.Property{ .value = expr, .key = key, .kind = .normal });
},
// This implements
// <div {"foo"} />