aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-09-21 12:20:53 -0700
committerGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-09-21 12:20:53 -0700
commit4a1573e007f984a9c1eb11a5fa003f73e84dc975 (patch)
treeb6531d739a5e2c66dcdc468691b6839531f0a9b9
parent0b4a34bbd6e07096212774759ca6e8a7f3922e46 (diff)
downloadbun-4a1573e007f984a9c1eb11a5fa003f73e84dc975.tar.gz
bun-4a1573e007f984a9c1eb11a5fa003f73e84dc975.tar.zst
bun-4a1573e007f984a9c1eb11a5fa003f73e84dc975.zip
decorator metadata defaults and rest args
-rw-r--r--src/js_parser.zig29
-rw-r--r--test/transpiler/decorator-metadata.test.ts52
2 files changed, 72 insertions, 9 deletions
diff --git a/src/js_parser.zig b/src/js_parser.zig
index a9f346caf..e4dbaf25b 100644
--- a/src/js_parser.zig
+++ b/src/js_parser.zig
@@ -6894,6 +6894,7 @@ fn NewParser_(
p.fn_or_arrow_data_parse.allow_super_call = opts.allow_super_call;
p.fn_or_arrow_data_parse.allow_super_property = opts.allow_super_property;
+ var rest_arg: bool = false;
var arg_has_decorators: bool = false;
var args = List(G.Arg){};
while (p.lexer.token != T.t_close_paren) {
@@ -6923,6 +6924,7 @@ fn NewParser_(
if (!func.flags.contains(.has_rest_arg) and p.lexer.token == T.t_dot_dot_dot) {
// p.markSyntaxFeature
try p.lexer.next();
+ rest_arg = true;
func.flags.insert(.has_rest_arg);
}
@@ -6970,9 +6972,17 @@ fn NewParser_(
// "function foo(a: any) {}"
if (p.lexer.token == .t_colon) {
try p.lexer.next();
- if (p.options.features.emit_decorator_metadata and opts.allow_ts_decorators and (opts.has_argument_decorators or opts.has_decorators or arg_has_decorators)) {
- ts_metadata = try p.skipTypeScriptTypeWithMetadata(.lowest);
+ if (!rest_arg) {
+ if (p.options.features.emit_decorator_metadata and
+ opts.allow_ts_decorators and
+ (opts.has_argument_decorators or opts.has_decorators or arg_has_decorators))
+ {
+ ts_metadata = try p.skipTypeScriptTypeWithMetadata(.lowest);
+ } else {
+ try p.skipTypeScriptType(.lowest);
+ }
} else {
+ // rest parameter is always object, leave metadata as m_none
try p.skipTypeScriptType(.lowest);
}
}
@@ -7015,6 +7025,7 @@ fn NewParser_(
}
try p.lexer.next();
+ rest_arg = false;
}
if (args.items.len > 0) {
func.args = args.items;
@@ -7044,8 +7055,12 @@ fn NewParser_(
} else {
try p.skipTypescriptReturnType();
}
- } else if (func.flags.contains(.is_async) and p.options.features.emit_decorator_metadata and opts.allow_ts_decorators and (opts.has_argument_decorators or opts.has_decorators)) {
- func.return_ts_metadata = .m_promise;
+ } else if (p.options.features.emit_decorator_metadata and opts.allow_ts_decorators and (opts.has_argument_decorators or opts.has_decorators)) {
+ if (func.flags.contains(.is_async)) {
+ func.return_ts_metadata = .m_promise;
+ } else {
+ func.return_ts_metadata = .m_undefined;
+ }
}
}
@@ -19445,11 +19460,7 @@ fn NewParser_(
fn serializeMetadata(p: *P, ts_metadata: TypeScript.Metadata) !Expr {
return switch (ts_metadata) {
- .m_none => p.newExpr(
- E.Undefined{},
- logger.Loc.Empty,
- ),
-
+ .m_none,
.m_any,
.m_unknown,
.m_object,
diff --git a/test/transpiler/decorator-metadata.test.ts b/test/transpiler/decorator-metadata.test.ts
index 861604430..9cc8cc718 100644
--- a/test/transpiler/decorator-metadata.test.ts
+++ b/test/transpiler/decorator-metadata.test.ts
@@ -491,4 +491,56 @@ describe("decorator metadata", () => {
expect(Reflect.getMetadata("design:returntype", A.prototype, "method1")).toBe(Promise);
});
+
+ test("rest parameters and defaults", () => {
+ function d1(target: any) {}
+ function d2(target: any, key: string) {}
+
+ @d1
+ class A {
+ @d2
+ // @ts-ignore
+ prop0: any[];
+
+ // @ts-ignore
+ constructor(a0) {}
+
+ @d2
+ // @ts-ignore
+ prop1;
+
+ @d2
+ method1() {}
+
+ @d2
+ // @ts-ignore
+ method2(...a0) {}
+
+ @d2
+ method3(a0: number, ...a1: []) {}
+
+ @d2
+ method4(...a0: any[]) {}
+ }
+
+ expect(Reflect.getMetadata("design:type", A.prototype, "prop0")).toBe(Array);
+ expect(Reflect.getMetadata("design:type", A.prototype, "prop1")).toBe(Object);
+
+ expect(Reflect.getMetadata("design:paramtypes", A.prototype, "method1")).toHaveLength(0);
+ expect(Reflect.getMetadata("design:type", A.prototype, "method1")).toBe(Function);
+ expect(Reflect.getMetadata("design:returntype", A.prototype, "method1")).toBeUndefined();
+
+ expect(Reflect.getMetadata("design:paramtypes", A.prototype, "method2")[0]).toBe(Object);
+ expect(Reflect.getMetadata("design:type", A.prototype, "method2")).toBe(Function);
+ expect(Reflect.getMetadata("design:returntype", A.prototype, "method2")).toBeUndefined();
+
+ expect(Reflect.getMetadata("design:paramtypes", A.prototype, "method3")[0]).toBe(Number);
+ expect(Reflect.getMetadata("design:paramtypes", A.prototype, "method3")[1]).toBe(Object);
+ expect(Reflect.getMetadata("design:type", A.prototype, "method3")).toBe(Function);
+ expect(Reflect.getMetadata("design:returntype", A.prototype, "method3")).toBeUndefined();
+
+ expect(Reflect.getMetadata("design:paramtypes", A.prototype, "method4")[0]).toBe(Object);
+ expect(Reflect.getMetadata("design:type", A.prototype, "method4")).toBe(Function);
+ expect(Reflect.getMetadata("design:returntype", A.prototype, "method4")).toBeUndefined();
+ });
});