Skip to content

Commit b93a2a9

Browse files
committed
fix #3781: add metadata to all decorated classes
1 parent 953dae9 commit b93a2a9

File tree

8 files changed

+247
-8
lines changed

8 files changed

+247
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
* Fix `Symbol.metadata` on classes without a class decorator ([#3781](https://github.com/evanw/esbuild/issues/3781))
6+
7+
This release fixes a bug with esbuild's support for the [decorator metadata proposal](https://github.com/tc39/proposal-decorator-metadata). Previously esbuild only added the `Symbol.metadata` property to decorated classes if there was a decorator on the class element itself. However, the proposal says that the `Symbol.metadata` property should be present on all classes that have any decorators at all, not just those with a decorator on the class element itself.
8+
59
* Allow unknown import attributes to be used with the `copy` loader ([#3792](https://github.com/evanw/esbuild/issues/3792))
610

711
Import attributes (the `with` keyword on `import` statements) are allowed to alter how that path is loaded. For example, esbuild cannot assume that it knows how to load `./bagel.js` as type `bagel`:

internal/bundler_tests/snapshots/snapshots_lower.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ var _Foo = class _Foo {
633633
_init = __decoratorStart(null);
634634
_foo = new WeakMap();
635635
__decorateElement(_init, 4, "foo", _foo_dec, _Foo, _foo);
636+
__decoratorMetadata(_init, _Foo);
636637
var Foo = _Foo;
637638

638639
---------- /out/base-instance-field.js ----------
@@ -646,6 +647,7 @@ var _Foo = class _Foo {
646647
};
647648
_init = __decoratorStart(null);
648649
__decorateElement(_init, 5, "foo", _foo_dec, _Foo);
650+
__decoratorMetadata(_init, _Foo);
649651
var Foo = _Foo;
650652

651653
---------- /out/base-instance-method.js ----------
@@ -662,6 +664,7 @@ var _Foo = class _Foo {
662664
};
663665
_init = __decoratorStart(null);
664666
__decorateElement(_init, 1, "foo", _foo_dec, _Foo);
667+
__decoratorMetadata(_init, _Foo);
665668
var Foo = _Foo;
666669

667670
---------- /out/base-static-accessor.js ----------
@@ -673,6 +676,7 @@ var _Foo = class _Foo {
673676
_init = __decoratorStart(null);
674677
_foo = new WeakMap();
675678
__decorateElement(_init, 12, "foo", _foo_dec, _Foo, _foo);
679+
__decoratorMetadata(_init, _Foo);
676680
__privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);
677681
var Foo = _Foo;
678682

@@ -684,6 +688,7 @@ var _Foo = class _Foo {
684688
};
685689
_init = __decoratorStart(null);
686690
__decorateElement(_init, 13, "foo", _foo_dec, _Foo);
691+
__decoratorMetadata(_init, _Foo);
687692
__publicField(_Foo, "foo", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);
688693
var Foo = _Foo;
689694

@@ -698,6 +703,7 @@ var _Foo = class _Foo {
698703
};
699704
_init = __decoratorStart(null);
700705
__decorateElement(_init, 9, "foo", _foo_dec, _Foo);
706+
__decoratorMetadata(_init, _Foo);
701707
__runInitializers(_init, 3, _Foo);
702708
var Foo = _Foo;
703709

@@ -713,6 +719,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
713719
_init = __decoratorStart(_a);
714720
_foo = new WeakMap();
715721
__decorateElement(_init, 4, "foo", _foo_dec, _Foo, _foo);
722+
__decoratorMetadata(_init, _Foo);
716723
var Foo = _Foo;
717724

718725
---------- /out/derived-instance-field.js ----------
@@ -726,6 +733,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
726733
};
727734
_init = __decoratorStart(_a);
728735
__decorateElement(_init, 5, "foo", _foo_dec, _Foo);
736+
__decoratorMetadata(_init, _Foo);
729737
var Foo = _Foo;
730738

731739
---------- /out/derived-instance-method.js ----------
@@ -742,6 +750,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
742750
};
743751
_init = __decoratorStart(_a);
744752
__decorateElement(_init, 1, "foo", _foo_dec, _Foo);
753+
__decoratorMetadata(_init, _Foo);
745754
var Foo = _Foo;
746755

747756
---------- /out/derived-static-accessor.js ----------
@@ -752,6 +761,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
752761
_init = __decoratorStart(_a);
753762
_foo = new WeakMap();
754763
__decorateElement(_init, 12, "foo", _foo_dec, _Foo, _foo);
764+
__decoratorMetadata(_init, _Foo);
755765
__privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);
756766
var Foo = _Foo;
757767

@@ -762,6 +772,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
762772
};
763773
_init = __decoratorStart(_a);
764774
__decorateElement(_init, 13, "foo", _foo_dec, _Foo);
775+
__decoratorMetadata(_init, _Foo);
765776
__publicField(_Foo, "foo", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);
766777
var Foo = _Foo;
767778

@@ -775,6 +786,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {
775786
};
776787
_init = __decoratorStart(_a);
777788
__decorateElement(_init, 9, "foo", _foo_dec, _Foo);
789+
__decoratorMetadata(_init, _Foo);
778790
__runInitializers(_init, 3, _Foo);
779791
var Foo = _Foo;
780792

internal/js_parser/js_parser_lower_class.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,9 +2083,9 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
20832083
classDecorators = ctx.decoratorClassDecorators
20842084
}
20852085

2086-
// Handle JavaScript decorators on the class itself
20872086
var decorateClassExpr js_ast.Expr
20882087
if classDecorators.Data != nil {
2088+
// Handle JavaScript decorators on the class itself
20892089
if ctx.decoratorContextRef == ast.InvalidRef {
20902090
ctx.decoratorContextRef = p.generateTempRef(tempRefNeedsDeclare, "_init")
20912091
}
@@ -2098,6 +2098,12 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
20982098
})
20992099
p.recordUsage(ctx.decoratorContextRef)
21002100
decorateClassExpr = js_ast.Assign(ctx.nameFunc(), decorateClassExpr)
2101+
} else if ctx.decoratorContextRef != ast.InvalidRef {
2102+
// Decorator metadata is present if there are any decorators on the class at all
2103+
decorateClassExpr = p.callRuntime(ctx.classLoc, "__decoratorMetadata", []js_ast.Expr{
2104+
{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},
2105+
ctx.nameFunc(),
2106+
})
21012107
}
21022108

21032109
// If this is true, we have removed some code from the class body that could
@@ -2203,7 +2209,7 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass
22032209
suffixExprs = append(suffixExprs, ctx.staticExperimentalDecorators...)
22042210

22052211
// For each element initializer of classExtraInitializers
2206-
if decorateClassExpr.Data != nil {
2212+
if classDecorators.Data != nil {
22072213
suffixExprs = append(suffixExprs, p.callRuntime(ctx.classLoc, "__runInitializers", []js_ast.Expr{
22082214
{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},
22092215
{Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: (0 << 1) | 1}},

internal/js_parser/js_parser_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,7 @@ class Foo {
20912091
}
20922092
_init = __decoratorStart(null);
20932093
__decorateElement(_init, 5, "x", _x_dec, Foo);
2094+
__decoratorMetadata(_init, Foo);
20942095
`)
20952096
expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec x() {} }",
20962097
`var _x_dec, _init;
@@ -2104,6 +2105,7 @@ class Foo {
21042105
}
21052106
_init = __decoratorStart(null);
21062107
__decorateElement(_init, 1, "x", _x_dec, Foo);
2108+
__decoratorMetadata(_init, Foo);
21072109
`)
21082110
expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec accessor x }",
21092111
`var _x_dec, _init, _x;
@@ -2116,6 +2118,7 @@ class Foo {
21162118
_init = __decoratorStart(null);
21172119
_x = new WeakMap();
21182120
__decorateElement(_init, 4, "x", _x_dec, Foo, _x);
2121+
__decoratorMetadata(_init, Foo);
21192122
`)
21202123
expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x }",
21212124
`var _x_dec, _init;
@@ -2124,6 +2127,7 @@ class Foo {
21242127
}
21252128
_init = __decoratorStart(null);
21262129
__decorateElement(_init, 13, "x", _x_dec, Foo);
2130+
__decoratorMetadata(_init, Foo);
21272131
__publicField(Foo, "x", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
21282132
`)
21292133
expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x() {} }",
@@ -2135,6 +2139,7 @@ class Foo {
21352139
}
21362140
_init = __decoratorStart(null);
21372141
__decorateElement(_init, 9, "x", _x_dec, Foo);
2142+
__decoratorMetadata(_init, Foo);
21382143
__runInitializers(_init, 3, Foo);
21392144
`)
21402145
expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static accessor x }",
@@ -2145,6 +2150,7 @@ class Foo {
21452150
_init = __decoratorStart(null);
21462151
_x = new WeakMap();
21472152
__decorateElement(_init, 12, "x", _x_dec, Foo, _x);
2153+
__decoratorMetadata(_init, Foo);
21482154
__privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
21492155
`)
21502156

internal/js_parser/ts_parser_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,7 @@ class Foo {
21362136
}
21372137
_init = __decoratorStart(null);
21382138
__decorateElement(_init, 5, "x", _x_dec, Foo);
2139+
__decoratorMetadata(_init, Foo);
21392140
`)
21402141
expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec x() {} }",
21412142
`var _x_dec, _init;
@@ -2149,6 +2150,7 @@ class Foo {
21492150
}
21502151
_init = __decoratorStart(null);
21512152
__decorateElement(_init, 1, "x", _x_dec, Foo);
2153+
__decoratorMetadata(_init, Foo);
21522154
`)
21532155
expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec accessor x }",
21542156
`var _x_dec, _init, _x;
@@ -2161,6 +2163,7 @@ class Foo {
21612163
_init = __decoratorStart(null);
21622164
_x = new WeakMap();
21632165
__decorateElement(_init, 4, "x", _x_dec, Foo, _x);
2166+
__decoratorMetadata(_init, Foo);
21642167
`)
21652168
expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static x }",
21662169
`var _x_dec, _init;
@@ -2169,6 +2172,7 @@ class Foo {
21692172
}
21702173
_init = __decoratorStart(null);
21712174
__decorateElement(_init, 13, "x", _x_dec, Foo);
2175+
__decoratorMetadata(_init, Foo);
21722176
__publicField(Foo, "x", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
21732177
`)
21742178
expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static x() {} }",
@@ -2180,6 +2184,7 @@ class Foo {
21802184
}
21812185
_init = __decoratorStart(null);
21822186
__decorateElement(_init, 9, "x", _x_dec, Foo);
2187+
__decoratorMetadata(_init, Foo);
21832188
__runInitializers(_init, 3, Foo);
21842189
`)
21852190
expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static accessor x }",
@@ -2190,6 +2195,7 @@ class Foo {
21902195
_init = __decoratorStart(null);
21912196
_x = new WeakMap();
21922197
__decorateElement(_init, 12, "x", _x_dec, Foo, _x);
2198+
__decoratorMetadata(_init, Foo);
21932199
__privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);
21942200
`)
21952201

internal/runtime/runtime.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ func Source(unsupportedJSFeatures compat.JSFeature) logger.Source {
266266
var __expectFn = fn => fn !== void 0 && typeof fn !== 'function' ? __typeError('Function expected') : fn
267267
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: fn =>
268268
done._ ? __typeError('Already initialized') : fns.push(__expectFn(fn || null)) })
269+
export var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol('metadata'), array[3])
269270
export var __runInitializers = (array, flags, self, value) => {
270271
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value)
271272
return value
@@ -306,7 +307,7 @@ func Source(unsupportedJSFeatures compat.JSFeature) logger.Source {
306307
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn)
307308
}
308309
309-
return k || (target[__knownSymbol('metadata')] = array[3]),
310+
return k || __decoratorMetadata(array, target),
310311
desc && __defProp(target, name, desc),
311312
p ? k ^ 4 ? extra : desc : target
312313
}

0 commit comments

Comments
 (0)