Deliver web apps with confidence 🚀
Find a file
Paul Gschwendtner ca07da4563 fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463)
In the Angular Package Format, we always shipped UMD bundles and previously even ES5 module output.
With V10, we removed the ES5 module output but kept the UMD ES5 output.

For this, we were able to remove our second TypeScript transpilation. Instead we started only
building ES2015 output and then downleveled it to ES5 UMD for the NPM packages. This worked
as expected but unveiled an issue in the `@angular/core` reflection capabilities.

In JIT mode, Angular determines constructor parameters (for DI) using the `ReflectionCapabilities`. The
reflection capabilities basically read runtime metadata of classes to determine the DI parameters. Such
metadata can be either stored in static class properties like `ctorParameters` or within TypeScript's `design:params`.

If Angular comes across a class that does not have any parameter metadata, it tries to detect if the
given class is actually delegating to an inherited class. It does this naively in JIT by checking if the
stringified class (function in ES5) matches a certain pattern. e.g.

```js
function MatTable() {
  var _this = _super.apply(this, arguments) || this;
```

These patterns are reluctant to changes of the class output. If a class is not recognized properly, the
DI parameters will be assumed empty and the class is **incorrectly** constructed without arguments.

This actually happened as part of v10 now. Since we downlevel ES2015 to ES5 (instead of previously
compiling sources directly to ES5), the class output changed slightly so that Angular no longer detects
it. e.g.

```js
var _this = _super.apply(this, __spread(arguments)) || this;
```

This happens because the ES2015 output will receive an auto-generated constructor if the class
defines class properties. This constructor is then already containing an explicit `super` call.

```js
export class MatTable extends CdkTable {
    constructor() {
        super(...arguments);
        this.disabled = true;
    }
}
```

If we then downlevel this file to ES5 with `--downlevelIteration`, TypeScript adjusts the `super` call so that
the spread operator is no longer used (not supported in ES5). The resulting super call is different to the
super call that would have been emitted if we would directly transpile to ES5. Ultimately, Angular no
longer detects such classes as having an delegate constructor -> and DI breaks.

We fix this by expanding the rather naive RegExp patterns used for the reflection capabilities
so that downleveled pass-through/delegate constructors are properly detected. There is a risk
of a false-positive as we cannot detect whether `__spread` is actually the TypeScript spread
helper, but given the reflection patterns already make lots of assumptions (e.g. that `super` is
actually the superclass, we should be fine making this assumption too. The false-positive would
not result in a broken app, but rather in unnecessary providers being injected (as a noop).

Fixes #38453

PR Close #38463
2020-08-17 10:55:37 -07:00
.circleci fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
.devcontainer build: update the recommended Dockerfile for VSCode remote development (#34697) 2020-01-09 13:31:14 -08:00
.github refactor(dev-infra): allow use-case and confusing types to be marked as 'triaged' (#38081) 2020-07-20 11:14:46 -07:00
.ng-dev build: update ng-dev config file for new commit message configuration (#38430) 2020-08-13 09:11:19 -07:00
.vscode build: Ignore .history for the xyz.local-history VSCode extension (#38121) 2020-07-17 13:33:39 -07:00
.yarn build: update to latest version of yarn (#36464) 2020-04-14 12:47:30 -07:00
aio test(docs-infra): remove deprecated ReflectiveInjector (#38408) 2020-08-13 12:56:13 -07:00
dev-infra feat(dev-infra): migrate to unified commit message types in commit message linting (#38430) 2020-08-13 09:11:17 -07:00
docs docs: remove duplicate https:// (#38199) 2020-07-23 10:54:44 -07:00
goldens fix(router): export DefaultRouteReuseStrategy to Router public_api (#31575) 2020-08-13 16:02:41 -07:00
integration ci: disable closure size tracking test (#38449) 2020-08-13 11:41:13 -07:00
modules refactor(dev-infra): ng_rollup_bundle rule should leverage @bazel/rollup (#37623) 2020-06-22 10:55:28 -07:00
packages fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
scripts style(dev-infra): enforce format on newly included files (#36940) 2020-06-12 15:06:41 -07:00
third_party build: move shims_for_IE to third_party directory (#37624) 2020-06-26 11:09:01 -07:00
tools build: run browsers tests on chromium locally (#38435) 2020-08-13 09:37:02 -07:00
.bazelignore build: add npm package manifest to npm_integration_test (#35669) 2020-02-26 12:58:35 -08:00
.bazelrc build: cleanup .bazelrc file to no longer set unused flags (#38124) 2020-08-03 12:53:11 -07:00
.bazelversion build: upgrade to bazel 3.2.0 and rules_nodejs 1.7.0 (#37358) 2020-06-08 09:15:50 -07:00
.clang-format feat(tooling): Add a .clang-format for automated JavaScript formatting. 2015-04-02 08:44:34 -07:00
.editorconfig build: use https link to editorconfig.org in .editorconfig (#27664) 2018-12-18 09:30:09 -08:00
.gitattributes test: fix ts api guardian and public guard tests on windows (#30105) 2019-04-26 16:32:22 -07:00
.gitignore build: Ignore .history for the xyz.local-history VSCode extension (#38121) 2020-07-17 13:33:39 -07:00
.gitmessage build: add .gitmessage file with commit message template (#37951) 2020-07-13 09:23:03 -07:00
.mailmap build: add a Git .mailmap with my new name (#19550) 2017-10-09 14:35:30 -07:00
.nvmrc build: migrate to node@12.14.1 (#34955) 2020-01-27 09:31:22 -08:00
.pullapprove.yml fix(dev-infra): update i18n-related file locations in PullApprove config (#38403) 2020-08-10 17:29:51 -07:00
.yarnrc build: update to latest version of yarn (#36464) 2020-04-14 12:47:30 -07:00
browser-providers.conf.js build: run browsers tests on chromium locally (#38435) 2020-08-13 09:37:02 -07:00
BUILD.bazel build: move shims_for_IE to third_party directory (#37624) 2020-06-26 11:09:01 -07:00
CHANGELOG.md release: cut the v10.1.0-next.5 release 2020-08-12 09:57:20 -07:00
CODE_OF_CONDUCT.md docs: fix community tab in GitHub by copying CoC 2018-02-27 19:02:30 -08:00
CONTRIBUTING.md docs: reformat and update CONTRIBUTING.md (#37951) 2020-07-13 09:23:03 -07:00
gulpfile.js build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
karma-js.conf.js fix(core): detect DI parameters in JIT mode for downleveled ES2015 classes (#38463) 2020-08-17 10:55:37 -07:00
LICENSE build: bump year (#34651) 2020-01-13 07:21:43 -08:00
package.json feat(dev-infra): save invalid commit message attempts to be restored on next commit attempt (#38304) 2020-08-13 08:45:25 -07:00
README.md docs: remove browserstack badge from readme (#35684) 2020-03-17 09:29:43 -07:00
test-events.js build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
test-main.js build: import in-memory-web-api project (#37182) 2020-06-15 14:28:37 -07:00
tslint.json build: Update file-header lint rule to Google LLC (#37205) 2020-05-26 14:26:58 -04:00
WORKSPACE build: upgrade to bazel 3.2.0 and rules_nodejs 1.7.0 (#37358) 2020-06-08 09:15:50 -07:00
yarn.lock feat(dev-infra): provide organization-wide merge-tool label configuration (#38223) 2020-08-05 10:53:17 -07:00
yarn.lock.readme.md build: remove travisci leftovers (#27979) 2019-01-09 10:41:16 -08:00

CircleCI Join the chat at https://gitter.im/angular/angular npm version

Angular

Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages.

Quickstart

Get started in 5 minutes.

Changelog

Learn about the latest improvements.

Want to help?

Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for contributing and then check out one of our issues in the hotlist: community-help.