diff --git a/packages/core/src/reflection/reflection_capabilities.ts b/packages/core/src/reflection/reflection_capabilities.ts index 75575ebb13..c4ad36405b 100644 --- a/packages/core/src/reflection/reflection_capabilities.ts +++ b/packages/core/src/reflection/reflection_capabilities.ts @@ -34,15 +34,22 @@ import {GetterFn, MethodFn, SetterFn} from './types'; * var _this = _super.apply(this, arguments) || this; * ``` * + * downleveled to ES5 with `downlevelIteration` for TypeScript < 4.2: * ``` * function MyClass() { * var _this = _super.apply(this, __spread(arguments)) || this; * ``` * + * or downleveled to ES5 with `downlevelIteration` for TypeScript >= 4.2: + * ``` + * function MyClass() { + * var _this = _super.apply(this, __spreadArray([], __read(arguments))) || this; + * ``` + * * More details can be found in: https://github.com/angular/angular/issues/38453. */ export const ES5_DELEGATE_CTOR = - /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*(arguments|[^()]+\(arguments\))\)/; + /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*(arguments|(?:[^()]+\(\[\],)?[^()]+\(arguments\))\)/; /** Regular expression that detects ES2015 classes which extend from other classes. */ export const ES2015_INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/; /** diff --git a/packages/core/test/BUILD.bazel b/packages/core/test/BUILD.bazel index 8827492936..746631ca27 100644 --- a/packages/core/test/BUILD.bazel +++ b/packages/core/test/BUILD.bazel @@ -27,7 +27,7 @@ genrule( $(execpath @npm//typescript/bin:tsc) $< --outDir $$es2015_out_dir --target ES2015 \ --types --module umd $(execpath @npm//typescript/bin:tsc) --outFile $@ $$es2015_out_file --allowJs \ - --types --target ES5 + --types --target ES5 --downlevelIteration """, tools = ["@npm//typescript/bin:tsc"], ) diff --git a/packages/core/test/reflection/reflector_spec.ts b/packages/core/test/reflection/reflector_spec.ts index 87123b7087..137edb7f88 100644 --- a/packages/core/test/reflection/reflector_spec.ts +++ b/packages/core/test/reflection/reflector_spec.ts @@ -202,13 +202,48 @@ class TestObj { }); // See: https://github.com/angular/angular/issues/38453 - it('should support ES2015 downleveled classes', () => { - const {ChildNoCtor, ChildNoCtorPrivateProps, ChildWithCtor} = - require('./es5_downleveled_inheritance_fixture'); + it('should support ES2015 downleveled classes (workspace TypeScript version) (downlevelIteration=true)', + () => { + const {ChildNoCtor, ChildNoCtorPrivateProps, ChildWithCtor} = + require('./es5_downleveled_inheritance_fixture'); - expect(isDelegateCtor(ChildNoCtor.toString())).toBe(true); - expect(isDelegateCtor(ChildNoCtorPrivateProps.toString())).toBe(true); - expect(isDelegateCtor(ChildWithCtor.toString())).toBe(false); + expect(isDelegateCtor(ChildNoCtor.toString())).toBe(true); + expect(isDelegateCtor(ChildNoCtorPrivateProps.toString())).toBe(true); + expect(isDelegateCtor(ChildWithCtor.toString())).toBe(false); + }); + + it('should support ES2015 downleveled classes ( { + const ChildNoCtor = `function ChildNoCtor() { + return _super !== null && _super.apply(this, arguments) || this; + }`; + const ChildNoCtorPrivateProps = `function ChildNoCtorPrivateProps() { + var _this = _super.apply(this, __spread(arguments)) || this; + _this.x = 10; + return _this; + }`; + const ChildWithCtor = `function ChildWithCtor() { + return _super.call(this) || this; + }`; + expect(isDelegateCtor(ChildNoCtor)).toBe(true); + expect(isDelegateCtor(ChildNoCtorPrivateProps)).toBe(true); + expect(isDelegateCtor(ChildWithCtor)).toBe(false); + }); + + it('should support ES2015 downleveled classes (>=TS4.2) (downlevelIteration=true)', () => { + const ChildNoCtor = `function ChildNoCtor() { + return _super !== null && _super.apply(this, arguments) || this; + }`; + const ChildNoCtorPrivateProps = `function ChildNoCtorPrivateProps() { + var _this = _super.apply(this, __spreadArray([], __read(arguments))) || this; + _this.x = 10; + return _this; + }`; + const ChildWithCtor = `function ChildWithCtor() { + return _super.call(this) || this; + }`; + expect(isDelegateCtor(ChildNoCtor)).toBe(true); + expect(isDelegateCtor(ChildNoCtorPrivateProps)).toBe(true); + expect(isDelegateCtor(ChildWithCtor)).toBe(false); }); it('should support ES2015 classes when minified', () => {