From b93a2a95ac697f4aa01471e0a383a25626f1998e Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Sun, 9 Jun 2024 16:50:45 -0400 Subject: [PATCH] fix #3781: add metadata to all decorated classes --- CHANGELOG.md | 4 + .../snapshots/snapshots_lower.txt | 12 ++ internal/js_parser/js_parser_lower_class.go | 10 +- internal/js_parser/js_parser_test.go | 6 + internal/js_parser/ts_parser_test.go | 6 + internal/runtime/runtime.go | 3 +- scripts/decorator-tests.js | 177 +++++++++++++++++- scripts/decorator-tests.ts | 37 +++- 8 files changed, 247 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66764c65ead..ffb890a177c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fix `Symbol.metadata` on classes without a class decorator ([#3781](https://github.com/evanw/esbuild/issues/3781)) + + 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. + * Allow unknown import attributes to be used with the `copy` loader ([#3792](https://github.com/evanw/esbuild/issues/3792)) 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`: diff --git a/internal/bundler_tests/snapshots/snapshots_lower.txt b/internal/bundler_tests/snapshots/snapshots_lower.txt index 4c653cc40db..83535f82394 100644 --- a/internal/bundler_tests/snapshots/snapshots_lower.txt +++ b/internal/bundler_tests/snapshots/snapshots_lower.txt @@ -633,6 +633,7 @@ var _Foo = class _Foo { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 4, "foo", _foo_dec, _Foo, _foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/base-instance-field.js ---------- @@ -646,6 +647,7 @@ var _Foo = class _Foo { }; _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/base-instance-method.js ---------- @@ -662,6 +664,7 @@ var _Foo = class _Foo { }; _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/base-static-accessor.js ---------- @@ -673,6 +676,7 @@ var _Foo = class _Foo { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 12, "foo", _foo_dec, _Foo, _foo); +__decoratorMetadata(_init, _Foo); __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo); var Foo = _Foo; @@ -684,6 +688,7 @@ var _Foo = class _Foo { }; _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); __publicField(_Foo, "foo", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo); var Foo = _Foo; @@ -698,6 +703,7 @@ var _Foo = class _Foo { }; _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); __runInitializers(_init, 3, _Foo); var Foo = _Foo; @@ -713,6 +719,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { _init = __decoratorStart(_a); _foo = new WeakMap(); __decorateElement(_init, 4, "foo", _foo_dec, _Foo, _foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/derived-instance-field.js ---------- @@ -726,6 +733,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { }; _init = __decoratorStart(_a); __decorateElement(_init, 5, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/derived-instance-method.js ---------- @@ -742,6 +750,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { }; _init = __decoratorStart(_a); __decorateElement(_init, 1, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); var Foo = _Foo; ---------- /out/derived-static-accessor.js ---------- @@ -752,6 +761,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { _init = __decoratorStart(_a); _foo = new WeakMap(); __decorateElement(_init, 12, "foo", _foo_dec, _Foo, _foo); +__decoratorMetadata(_init, _Foo); __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo); var Foo = _Foo; @@ -762,6 +772,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { }; _init = __decoratorStart(_a); __decorateElement(_init, 13, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); __publicField(_Foo, "foo", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo); var Foo = _Foo; @@ -775,6 +786,7 @@ var _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) { }; _init = __decoratorStart(_a); __decorateElement(_init, 9, "foo", _foo_dec, _Foo); +__decoratorMetadata(_init, _Foo); __runInitializers(_init, 3, _Foo); var Foo = _Foo; diff --git a/internal/js_parser/js_parser_lower_class.go b/internal/js_parser/js_parser_lower_class.go index 3f6f7d7d161..944b0e42509 100644 --- a/internal/js_parser/js_parser_lower_class.go +++ b/internal/js_parser/js_parser_lower_class.go @@ -2083,9 +2083,9 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass classDecorators = ctx.decoratorClassDecorators } - // Handle JavaScript decorators on the class itself var decorateClassExpr js_ast.Expr if classDecorators.Data != nil { + // Handle JavaScript decorators on the class itself if ctx.decoratorContextRef == ast.InvalidRef { ctx.decoratorContextRef = p.generateTempRef(tempRefNeedsDeclare, "_init") } @@ -2098,6 +2098,12 @@ func (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClass }) p.recordUsage(ctx.decoratorContextRef) decorateClassExpr = js_ast.Assign(ctx.nameFunc(), decorateClassExpr) + } else if ctx.decoratorContextRef != ast.InvalidRef { + // Decorator metadata is present if there are any decorators on the class at all + decorateClassExpr = p.callRuntime(ctx.classLoc, "__decoratorMetadata", []js_ast.Expr{ + {Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}}, + ctx.nameFunc(), + }) } // 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 suffixExprs = append(suffixExprs, ctx.staticExperimentalDecorators...) // For each element initializer of classExtraInitializers - if decorateClassExpr.Data != nil { + if classDecorators.Data != nil { suffixExprs = append(suffixExprs, p.callRuntime(ctx.classLoc, "__runInitializers", []js_ast.Expr{ {Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}}, {Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: (0 << 1) | 1}}, diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index 98c3df73adc..9c83c23f27d 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -2091,6 +2091,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 5, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec x() {} }", `var _x_dec, _init; @@ -2104,6 +2105,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 1, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec accessor x }", `var _x_dec, _init, _x; @@ -2116,6 +2118,7 @@ class Foo { _init = __decoratorStart(null); _x = new WeakMap(); __decorateElement(_init, 4, "x", _x_dec, Foo, _x); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x }", `var _x_dec, _init; @@ -2124,6 +2127,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 13, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); __publicField(Foo, "x", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo); `) expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static x() {} }", @@ -2135,6 +2139,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 9, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); __runInitializers(_init, 3, Foo); `) expectPrintedWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec static accessor x }", @@ -2145,6 +2150,7 @@ class Foo { _init = __decoratorStart(null); _x = new WeakMap(); __decorateElement(_init, 12, "x", _x_dec, Foo, _x); +__decoratorMetadata(_init, Foo); __privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo); `) diff --git a/internal/js_parser/ts_parser_test.go b/internal/js_parser/ts_parser_test.go index 601a1572136..20b8483dfb7 100644 --- a/internal/js_parser/ts_parser_test.go +++ b/internal/js_parser/ts_parser_test.go @@ -2136,6 +2136,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 5, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec x() {} }", `var _x_dec, _init; @@ -2149,6 +2150,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 1, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec accessor x }", `var _x_dec, _init, _x; @@ -2161,6 +2163,7 @@ class Foo { _init = __decoratorStart(null); _x = new WeakMap(); __decorateElement(_init, 4, "x", _x_dec, Foo, _x); +__decoratorMetadata(_init, Foo); `) expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static x }", `var _x_dec, _init; @@ -2169,6 +2172,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 13, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); __publicField(Foo, "x", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo); `) expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static x() {} }", @@ -2180,6 +2184,7 @@ class Foo { } _init = __decoratorStart(null); __decorateElement(_init, 9, "x", _x_dec, Foo); +__decoratorMetadata(_init, Foo); __runInitializers(_init, 3, Foo); `) expectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, "class Foo { @dec static accessor x }", @@ -2190,6 +2195,7 @@ class Foo { _init = __decoratorStart(null); _x = new WeakMap(); __decorateElement(_init, 12, "x", _x_dec, Foo, _x); +__decoratorMetadata(_init, Foo); __privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo); `) diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index a56c7bed444..cca5e98122c 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -266,6 +266,7 @@ func Source(unsupportedJSFeatures compat.JSFeature) logger.Source { var __expectFn = fn => fn !== void 0 && typeof fn !== 'function' ? __typeError('Function expected') : fn var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: fn => done._ ? __typeError('Already initialized') : fns.push(__expectFn(fn || null)) }) + export var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol('metadata'), array[3]) export var __runInitializers = (array, flags, self, value) => { 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) return value @@ -306,7 +307,7 @@ func Source(unsupportedJSFeatures compat.JSFeature) logger.Source { else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn) } - return k || (target[__knownSymbol('metadata')] = array[3]), + return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target } diff --git a/scripts/decorator-tests.js b/scripts/decorator-tests.js index 22113d10bbc..d47f44fab74 100644 --- a/scripts/decorator-tests.js +++ b/scripts/decorator-tests.js @@ -11,6 +11,7 @@ var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata" var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"]; var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn; var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) }); +var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]); var __runInitializers = (array, flags, self, value) => { 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); return value; @@ -37,7 +38,7 @@ var __decorateElement = (array, flags, name, decorators, target, extra) => { else if (typeof it !== "object" || it === null) __typeError("Object expected"); else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn); } - return k || (target[__knownSymbol("metadata")] = array[3]), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target; + return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target; }; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); @@ -49,6 +50,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce if (!("metadata" in Symbol)) { Symbol.metadata = Symbol("Symbol.metadata"); } +if (!(Symbol.metadata in Function)) { + Object.defineProperty(Function.prototype, Symbol.metadata, { value: null }); +} const tests = { // Class decorators "Class decorators: Basic statement": () => { @@ -487,6 +491,7 @@ const tests = { __decorateElement(_init, 1, "foo", _foo_dec, Foo2); __decorateElement(_init, 1, _b, _bar_dec, Foo2); __decorateElement(_init, 1, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => Foo2.prototype.foo, old["foo"]); assertEq(() => Foo2.prototype[bar], old[bar]); assertEq(() => Foo2.prototype[baz], old[baz]); @@ -521,6 +526,7 @@ const tests = { __decorateElement(_init, 9, "foo", _foo_dec, Foo2); __decorateElement(_init, 9, _b, _bar_dec, Foo2); __decorateElement(_init, 9, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => Foo2.foo, old["foo"]); assertEq(() => Foo2[bar], old[bar]); @@ -558,6 +564,7 @@ const tests = { foo_fn = function() { }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, _Foo); $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn); let Foo2 = _Foo; assertEq(() => $foo, old); @@ -592,6 +599,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(_Foo, _Foo_static); + __decoratorMetadata(_init, _Foo); __runInitializers(_init, 3, _Foo); $foo = __privateMethod(_Foo, _Foo_static, foo_fn); let Foo2 = _Foo; @@ -619,6 +627,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => Foo2.prototype.foo, bar); assertEq(() => new Foo2().foo(), 124); }, @@ -639,6 +648,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 123); assertEq(() => Foo2.foo, bar); @@ -668,6 +678,7 @@ const tests = { return this.bar; }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, _Foo); $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn); let Foo2 = _Foo; assertEq(() => $foo, bar); @@ -693,6 +704,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(_Foo, _Foo_static); + __decoratorMetadata(_init, _Foo); __runInitializers(_init, 3, _Foo); __publicField(_Foo, "bar", 123); $foo = __privateMethod(_Foo, _Foo_static, foo_fn); @@ -733,6 +745,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); log.push(3); new Foo2().foo(); log.push(7); @@ -769,6 +782,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); log.push(3); Foo2.foo(); @@ -812,6 +826,7 @@ const tests = { return log.push(6); }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, _Foo); $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn); let Foo2 = _Foo; log.push(3); @@ -853,6 +868,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(_Foo, _Foo_static); + __decoratorMetadata(_init, _Foo); __runInitializers(_init, 3, _Foo); $foo = __privateMethod(_Foo, _Foo_static, foo_fn); let Foo2 = _Foo; @@ -878,6 +894,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Method decorators: Return null (static method)": () => { @@ -893,6 +910,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -914,6 +932,7 @@ const tests = { foo_fn = function() { }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Method decorators: Return null (private static method)": () => { @@ -931,6 +950,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -950,6 +970,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Method decorators: Return object (static method)": () => { @@ -965,6 +986,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -986,6 +1008,7 @@ const tests = { foo_fn = function() { }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Method decorators: Return object (private static method)": () => { @@ -1003,6 +1026,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -1029,6 +1053,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 1, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -1054,6 +1079,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 9, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -1083,6 +1109,7 @@ const tests = { foo_fn = function() { }; foo_fn = __decorateElement(_init, 17, "#foo", _foo_dec, _Foo_instances, foo_fn); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -1110,6 +1137,7 @@ const tests = { }; foo_fn = __decorateElement(_init, 25, "#foo", _foo_dec, _Foo_static, foo_fn); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -1146,6 +1174,7 @@ const tests = { __decorateElement(_init, 5, "foo", _foo_dec, Foo2); __decorateElement(_init, 5, _b, _bar_dec, Foo2); __decorateElement(_init, 5, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => new Foo2().foo, 123); assertEq(() => new Foo2()[bar], 123); assertEq(() => new Foo2()[baz], 123); @@ -1176,6 +1205,7 @@ const tests = { __decorateElement(_init, 13, "foo", _foo_dec, Foo2); __decorateElement(_init, 13, _b, _bar_dec, Foo2); __decorateElement(_init, 13, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); __publicField(Foo2, "foo", __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2); __publicField(Foo2, _b, __runInitializers(_init, 12, Foo2, 123)), __runInitializers(_init, 15, Foo2); __publicField(Foo2, _a, __runInitializers(_init, 16, Foo2, 123)), __runInitializers(_init, 19, Foo2); @@ -1213,6 +1243,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _foo); assertEq(() => get$foo(new Foo2()), 123); lateAsserts(); @@ -1243,6 +1274,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2); get$foo = (x) => __privateGet(x, _foo); assertEq(() => get$foo(Foo2), 123); @@ -1267,6 +1299,7 @@ const tests = { _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, Foo2); __decorateElement(_init, 5, "bar", _bar_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => log + "", ""); var obj = new Foo2(); assertEq(() => obj.foo, 3); @@ -1290,6 +1323,7 @@ const tests = { _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, _Foo); __decorateElement(_init, 13, "bar", _bar_dec, _Foo); + __decoratorMetadata(_init, _Foo); foo = _Foo; __publicField(_Foo, "foo", __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo); __publicField(_Foo, "bar", __runInitializers(_init, 12, _Foo)), __runInitializers(_init, 15, _Foo); @@ -1323,6 +1357,7 @@ const tests = { _bar = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); __decorateElement(_init, 21, "#bar", _bar_dec, _bar); + __decoratorMetadata(_init, Foo2); has$foo = (x) => __privateIn(_foo, x); has$bar = (x) => __privateIn(_bar, x); get$foo = (x) => __privateGet(x, _foo); @@ -1356,6 +1391,7 @@ const tests = { _bar = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); __decorateElement(_init, 29, "#bar", _bar_dec, _bar); + __decoratorMetadata(_init, _Foo); foo = _Foo; has$foo = (x) => __privateIn(_foo, x); has$bar = (x) => __privateIn(_bar, x); @@ -1388,6 +1424,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); log.push(3); var obj = new Foo2(); log.push(6); @@ -1411,6 +1448,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __publicField(Foo2, "foo", __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2); log.push(5); assertEq(() => Foo2.foo, 5); @@ -1438,6 +1476,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _foo); log.push(3); var obj = new Foo2(); @@ -1464,6 +1503,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2); get$foo = (x) => __privateGet(x, _foo); log.push(5); @@ -1484,6 +1524,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Field decorators: Return null (static field)": () => { @@ -1497,6 +1538,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __publicField(Foo2, "foo", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -1515,6 +1557,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Field decorators: Return null (private static field)": () => { @@ -1529,6 +1572,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -1546,6 +1590,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Field decorators: Return object (static field)": () => { @@ -1559,6 +1604,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __publicField(Foo2, "foo", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -1577,6 +1623,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Field decorators: Return object (private static field)": () => { @@ -1591,6 +1638,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -1615,6 +1663,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 5, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -1638,6 +1687,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 13, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __publicField(Foo2, "foo", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -1664,6 +1714,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 21, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -1688,6 +1739,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 29, "#foo", _foo_dec, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -1728,6 +1780,7 @@ const tests = { __decorateElement(_init, 2, "foo", _foo_dec, Foo2); __decorateElement(_init, 2, _b, _bar_dec, Foo2); __decorateElement(_init, 2, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => new Foo2().foo, 123); assertEq(() => new Foo2()[bar], 123); assertEq(() => new Foo2()[baz], 123); @@ -1763,6 +1816,7 @@ const tests = { __decorateElement(_init, 10, "foo", _foo_dec, Foo2); __decorateElement(_init, 10, _b, _bar_dec, Foo2); __decorateElement(_init, 10, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 123); assertEq(() => Foo2.foo, 123); @@ -1802,6 +1856,7 @@ const tests = { return __privateGet(this, _bar); }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _Foo_instances, foo_get); assertEq(() => get$foo(new Foo2()), 123); lateAsserts(); @@ -1835,6 +1890,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __privateAdd(Foo2, _bar, 123); get$foo = (x) => __privateGet(x, _Foo_static, foo_get); @@ -1862,6 +1918,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 2, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, "foo").get, bar); assertEq(() => new Foo2().foo, 124); }, @@ -1882,6 +1939,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 10, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 123); assertEq(() => Object.getOwnPropertyDescriptor(Foo2, "foo").get, bar); @@ -1912,6 +1970,7 @@ const tests = { return __privateGet(this, _bar); }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _Foo_instances, foo_get); assertEq(() => get$foo(new Foo2()), 124); }, @@ -1936,6 +1995,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __privateAdd(Foo2, _bar, 123); get$foo = (x) => __privateGet(x, _Foo_static, foo_get); @@ -1974,6 +2034,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 2, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); log.push(3); new Foo2().foo; log.push(7); @@ -2010,6 +2071,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 10, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); log.push(3); Foo2.foo; @@ -2053,6 +2115,7 @@ const tests = { return log.push(6); }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _Foo_instances, foo_get); log.push(3); assertEq(() => get$foo(new Foo2()), 7); @@ -2092,6 +2155,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); get$foo = (x) => __privateGet(x, _Foo_static, foo_get); log.push(3); @@ -2116,6 +2180,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 2, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Getter decorators: Return null (static getter)": () => { @@ -2132,6 +2197,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 10, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2154,6 +2220,7 @@ const tests = { return; }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Getter decorators: Return null (private static getter)": () => { @@ -2172,6 +2239,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2192,6 +2260,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 2, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Getter decorators: Return object (static getter)": () => { @@ -2208,6 +2277,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 10, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2230,6 +2300,7 @@ const tests = { return; }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Getter decorators: Return object (private static getter)": () => { @@ -2248,6 +2319,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2275,6 +2347,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 2, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -2301,6 +2374,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 10, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -2331,6 +2405,7 @@ const tests = { return; }; foo_get = __decorateElement(_init, 18, "#foo", _foo_dec, _Foo_instances, foo_get); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -2359,6 +2434,7 @@ const tests = { }; foo_get = __decorateElement(_init, 26, "#foo", _foo_dec, _Foo_static, foo_get); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -2402,6 +2478,7 @@ const tests = { __decorateElement(_init, 3, "foo", _foo_dec, Foo2); __decorateElement(_init, 3, _b, _bar_dec, Foo2); __decorateElement(_init, 3, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); var obj = new Foo2(); obj.foo = 321; assertEq(() => obj.bar, 321); @@ -2444,6 +2521,7 @@ const tests = { __decorateElement(_init, 11, "foo", _foo_dec, Foo2); __decorateElement(_init, 11, _b, _bar_dec, Foo2); __decorateElement(_init, 11, _a, _baz_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 0); Foo2.foo = 321; @@ -2489,6 +2567,7 @@ const tests = { this.bar = x; }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); set$foo = (x, y) => { __privateSet(x, _Foo_instances, y, foo_set); }; @@ -2528,6 +2607,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 0); set$foo = (x, y) => { @@ -2558,6 +2638,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 3, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, "foo").set, bar); var obj = new Foo2(); obj.foo = 321; @@ -2580,6 +2661,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 11, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 123); assertEq(() => Object.getOwnPropertyDescriptor(Foo2, "foo").set, bar); @@ -2610,6 +2692,7 @@ const tests = { this.bar = x; }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); set$foo = (x, y) => { __privateSet(x, _Foo_instances, y, foo_set); }; @@ -2637,6 +2720,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); __publicField(Foo2, "bar", 123); set$foo = (x, y) => { @@ -2678,6 +2762,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 3, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); log.push(3); new Foo2().foo = 123; log.push(7); @@ -2714,6 +2799,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 11, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); log.push(3); Foo2.foo = 123; @@ -2757,6 +2843,7 @@ const tests = { log.push(6); }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); set$foo = (x, y) => { __privateSet(x, _Foo_instances, y, foo_set); }; @@ -2798,6 +2885,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); set$foo = (x, y) => { __privateSet(x, _Foo_static, y, foo_set); @@ -2823,6 +2911,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 3, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Setter decorators: Return null (static setter)": () => { @@ -2838,6 +2927,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 11, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2859,6 +2949,7 @@ const tests = { foo_set = function(x) { }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Setter decorators: Return null (private static setter)": () => { @@ -2876,6 +2967,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2895,6 +2987,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 3, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Setter decorators: Return object (static setter)": () => { @@ -2910,6 +3003,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 11, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2931,6 +3025,7 @@ const tests = { foo_set = function(x) { }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Setter decorators: Return object (private static setter)": () => { @@ -2948,6 +3043,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); }, TypeError); }, @@ -2974,6 +3070,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 3, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -2999,6 +3096,7 @@ const tests = { } _init = __decoratorStart(null); __decorateElement(_init, 11, "foo", _foo_dec, Foo2); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -3028,6 +3126,7 @@ const tests = { foo_set = function(x) { }; foo_set = __decorateElement(_init, 19, "#foo", _foo_dec, _Foo_instances, foo_set); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -3055,6 +3154,7 @@ const tests = { }; foo_set = __decorateElement(_init, 27, "#foo", _foo_dec, _Foo_static, foo_set); __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __runInitializers(_init, 3, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -3097,6 +3197,7 @@ const tests = { __decorateElement(_init, 4, "foo", _foo_dec, Foo2, _foo); __decorateElement(_init, 4, _b, _bar_dec, Foo2, __b); __decorateElement(_init, 4, _a, _baz_dec, Foo2, __a); + __decoratorMetadata(_init, Foo2); var obj = new Foo2(); obj.foo = 321; assertEq(() => obj.foo, 321); @@ -3137,6 +3238,7 @@ const tests = { __decorateElement(_init, 12, "foo", _foo_dec, Foo2, _foo); __decorateElement(_init, 12, _b, _bar_dec, Foo2, __b); __decorateElement(_init, 12, _a, _baz_dec, Foo2, __a); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 0)), __runInitializers(_init, 11, Foo2); __privateAdd(Foo2, __b, __runInitializers(_init, 12, Foo2, 0)), __runInitializers(_init, 15, Foo2); __privateAdd(Foo2, __a, __runInitializers(_init, 16, Foo2, 0)), __runInitializers(_init, 19, Foo2); @@ -3183,6 +3285,7 @@ const tests = { _foo = new WeakMap(); _Foo_instances = new WeakSet(); _a = __decorateElement(_init, 20, "#foo", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set; + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _Foo_instances, foo_get); set$foo = (x, y) => { __privateSet(x, _Foo_instances, y, foo_set); @@ -3224,6 +3327,7 @@ const tests = { _Foo_static = new WeakSet(); _a = __decorateElement(_init, 28, "#foo", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set; __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 0)), __runInitializers(_init, 11, Foo2); get$foo = (x) => __privateGet(x, _Foo_static, foo_get); set$foo = (x, y) => { @@ -3259,6 +3363,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 4, "foo", _foo_dec, Foo2, _foo); + __decoratorMetadata(_init, Foo2); assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, "foo").get, get); assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, "foo").set, set); var obj = new Foo2(); @@ -3290,6 +3395,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 12, "foo", _foo_dec, _Foo, _foo); + __decoratorMetadata(_init, _Foo); foo = _Foo; __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo); let Foo2 = _Foo; @@ -3329,6 +3435,7 @@ const tests = { _foo = new WeakMap(); _Foo_instances = new WeakSet(); _a = __decorateElement(_init, 20, "#foo", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set; + __decoratorMetadata(_init, Foo2); get$foo = (x) => __privateGet(x, _Foo_instances, foo_get); set$foo = (x, y) => { __privateSet(x, _Foo_instances, y, foo_set); @@ -3366,6 +3473,7 @@ const tests = { _Foo_static = new WeakSet(); _a = __decorateElement(_init, 28, "#foo", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set; __privateAdd(_Foo, _Foo_static); + __decoratorMetadata(_init, _Foo); foo = _Foo; get$foo = (x) => __privateGet(x, _Foo_static, foo_get); set$foo = (x, y) => { @@ -3392,6 +3500,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 4, "foo", _foo_dec, Foo2, _foo); + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Auto-accessor decorators: Return null (static auto-accessor)": () => { @@ -3406,6 +3515,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 12, "foo", _foo_dec, Foo2, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -3426,6 +3536,7 @@ const tests = { _foo = new WeakMap(); _Foo_instances = new WeakSet(); _a = __decorateElement(_init, 20, "#foo", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set; + __decoratorMetadata(_init, Foo2); }, TypeError); }, "Auto-accessor decorators: Return null (private static auto-accessor)": () => { @@ -3442,6 +3553,7 @@ const tests = { _Foo_static = new WeakSet(); _a = __decorateElement(_init, 28, "#foo", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set; __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); }, TypeError); }, @@ -3467,6 +3579,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 4, "foo", _foo_dec, Foo2, _foo); + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -3491,6 +3604,7 @@ const tests = { _init = __decoratorStart(null); _foo = new WeakMap(); __decorateElement(_init, 12, "foo", _foo_dec, Foo2, _foo); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -3519,6 +3633,7 @@ const tests = { _foo = new WeakMap(); _Foo_instances = new WeakSet(); _a = __decorateElement(_init, 20, "#foo", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set; + __decoratorMetadata(_init, Foo2); assertEq(() => got, void 0); const instance = new Foo2(); assertEq(() => got.this, instance); @@ -3545,6 +3660,7 @@ const tests = { _Foo_static = new WeakSet(); _a = __decorateElement(_init, 28, "#foo", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set; __privateAdd(Foo2, _Foo_static); + __decoratorMetadata(_init, Foo2); __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2); assertEq(() => got.this, Foo2); assertEq(() => got.args.length, 0); @@ -4153,7 +4269,7 @@ const tests = { }, // Decorator metadata "Decorator metadata: class statement": () => { - var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _a, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _b, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _staticField, _staticAccessor2, _c, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set; + var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _a, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _b, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _staticField, _staticAccessor2, _c, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set, _x_dec, _init3, _y_dec, _d, _init4; let counter = 0; const dec = (_, ctx) => { ctx.metadata[ctx.name] = counter++; @@ -4272,11 +4388,39 @@ const tests = { const foo = Foo2[Symbol.metadata]; const bar = Bar[Symbol.metadata]; assertEq(() => order(foo), "0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,"); + assertEq(() => Object.getPrototypeOf(foo), null); assertEq(() => order(bar), "0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21"); assertEq(() => Object.getPrototypeOf(bar), foo); + class FooNoDec { + } + class BarNoDec extends FooNoDec { + } + assertEq(() => FooNoDec[Symbol.metadata], null); + assertEq(() => BarNoDec[Symbol.metadata], null); + _x_dec = [dec]; + class FooOneDec { + constructor() { + __publicField(this, "x", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this); + } + } + _init3 = __decoratorStart(null); + __decorateElement(_init3, 5, "x", _x_dec, FooOneDec); + __decoratorMetadata(_init3, FooOneDec); + class BarOneDec extends (_d = FooOneDec, _y_dec = [dec], _d) { + constructor() { + super(...arguments); + __publicField(this, "y", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this); + } + } + _init4 = __decoratorStart(_d); + __decorateElement(_init4, 5, "y", _y_dec, BarOneDec); + __decoratorMetadata(_init4, BarOneDec); + assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]), JSON.stringify({ x: 22 })); + assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]), JSON.stringify({ y: 23 })); + assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]), FooOneDec[Symbol.metadata]); }, "Decorator metadata: class expression": () => { - var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _a, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _b, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _c, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _d, _staticField, _staticAccessor2, _e, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set; + var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _a, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _b, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _c, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _d, _staticField, _staticAccessor2, _e, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set, _x_dec, _init3, _f, _y_dec, _g, _init4, _h; let counter = 0; const dec = (_, ctx) => { ctx.metadata[ctx.name] = counter++; @@ -4345,8 +4489,29 @@ const tests = { const foo = Foo2[Symbol.metadata]; const bar = Bar[Symbol.metadata]; assertEq(() => order(foo), "0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,"); + assertEq(() => Object.getPrototypeOf(foo), null); assertEq(() => order(bar), "0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21"); assertEq(() => Object.getPrototypeOf(bar), foo); + const FooNoDec = class { + }; + const BarNoDec = class extends FooNoDec { + }; + assertEq(() => FooNoDec[Symbol.metadata], null); + assertEq(() => BarNoDec[Symbol.metadata], null); + const FooOneDec = (_x_dec = [dec], _f = class { + constructor() { + __publicField(this, "x", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this); + } + }, _init3 = __decoratorStart(null), __decorateElement(_init3, 5, "x", _x_dec, _f), __decoratorMetadata(_init3, _f), _f); + const BarOneDec = (_h = class extends (_g = FooOneDec, _y_dec = [dec], _g) { + constructor() { + super(...arguments); + __publicField(this, "y", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this); + } + }, _init4 = __decoratorStart(_g), __decorateElement(_init4, 5, "y", _y_dec, _h), __decoratorMetadata(_init4, _h), _h); + assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]), JSON.stringify({ x: 22 })); + assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]), JSON.stringify({ y: 23 })); + assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]), FooOneDec[Symbol.metadata]); }, // Initializer order "Initializer order (public members, class statement)": () => { @@ -5152,7 +5317,11 @@ const tests = { function prettyPrint(x) { if (x && x.prototype && x.prototype.constructor === x) return "class"; if (typeof x === "string") return JSON.stringify(x); - return x; + try { + return x + ""; + } catch { + return "typeof " + typeof x; + } } function assertEq(callback, expected) { let details; diff --git a/scripts/decorator-tests.ts b/scripts/decorator-tests.ts index c84f76acc0c..b29336b008e 100644 --- a/scripts/decorator-tests.ts +++ b/scripts/decorator-tests.ts @@ -2,6 +2,9 @@ if (!('metadata' in Symbol as any)) { (Symbol as any).metadata = Symbol('Symbol.metadata') } +if (!(Symbol.metadata in Function)) { + Object.defineProperty((Function as any).prototype, Symbol.metadata, { value: null }) +} const tests: Record Promise | void> = { // Class decorators @@ -2847,8 +2850,22 @@ const tests: Record Promise | void> = { const foo = Foo[Symbol.metadata]! const bar = Bar[Symbol.metadata]! assertEq(() => order(foo), '0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,') + assertEq(() => Object.getPrototypeOf(foo), null) assertEq(() => order(bar), '0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21') assertEq(() => Object.getPrototypeOf(bar), foo) + + // Test an undecorated class + class FooNoDec { } + class BarNoDec extends FooNoDec { } + assertEq(() => FooNoDec[Symbol.metadata], null) + assertEq(() => BarNoDec[Symbol.metadata], null) + + // Test a class with no class decorator + class FooOneDec { @dec x: undefined } + class BarOneDec extends FooOneDec { @dec y: undefined } + assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]!), JSON.stringify({ x: 22 })) + assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]!), JSON.stringify({ y: 23 })) + assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]!), FooOneDec[Symbol.metadata]!) }, 'Decorator metadata: class expression': () => { let counter = 0 @@ -2892,8 +2909,22 @@ const tests: Record Promise | void> = { const foo = Foo[Symbol.metadata]! const bar = Bar[Symbol.metadata]! assertEq(() => order(foo), '0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,') + assertEq(() => Object.getPrototypeOf(foo), null) assertEq(() => order(bar), '0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21') assertEq(() => Object.getPrototypeOf(bar), foo) + + // Test an undecorated class + const FooNoDec = class { } + const BarNoDec = class extends FooNoDec { } + assertEq(() => FooNoDec[Symbol.metadata], null) + assertEq(() => BarNoDec[Symbol.metadata], null) + + // Test a class with no class decorator + const FooOneDec = class { @dec x: undefined } + const BarOneDec = class extends FooOneDec { @dec y: undefined } + assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]!), JSON.stringify({ x: 22 })) + assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]!), JSON.stringify({ y: 23 })) + assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]!), FooOneDec[Symbol.metadata]!) }, // Initializer order @@ -3818,7 +3849,11 @@ const tests: Record Promise | void> = { function prettyPrint(x: any): any { if (x && x.prototype && x.prototype.constructor === x) return 'class' if (typeof x === 'string') return JSON.stringify(x) - return x + try { + return x + '' + } catch { + return 'typeof ' + typeof x // Handle values that don't implement "toString" + } } function assertEq(callback: () => T, expected: T): boolean {