Go to file
Alex Rickabaugh 4213e8d5f0 fix(compiler): switch to 'referencedFiles' for shim generation (#36211)
Shim generation was built on a lie.

Shims are files added to the program which aren't original files authored by
the user, but files authored effectively by the compiler. These fall into
two categories: files which will be generated (like the .ngfactory shims we
generate for View Engine compatibility) as well as files used internally in
compilation (like the __ng_typecheck__.ts file).

Previously, shim generation was driven by the `rootFiles` passed to the
compiler as input. These are effectively the `files` listed in the
`tsconfig.json`. Each shim generator (e.g. the `FactoryGenerator`) would
examine the `rootFiles` and produce a list of shim file names which it would
be responsible for generating. These names would then be added to the
`rootFiles` when the program was created.

The fatal flaw here is that `rootFiles` does not always account for all of
the files in the program. In fact, it's quite rare that it does. Users don't
typically specify every file directly in `files`. Instead, they rely on
TypeScript, during program creation, starting with a few root files and
transitively discovering all of the files in the program.

This happens, however, during `ts.createProgram`, which is too late to add
new files to the `rootFiles` list.

As a result, shim generation was only including shims for files actually
listed in the `tsconfig.json` file, and not for the transitive set of files
in the user's program as it should.

This commit completely rewrites shim generation to use a different technique
for adding files to the program, inspired by View Engine's shim generator.
In this new technique, as the program is being created and `ts.SourceFile`s
are being requested from the `NgCompilerHost`, shims for those files are
generated and a reference to them is patched onto the original file's
`ts.SourceFile.referencedFiles`. This causes TS to think that the original
file references the shim, and causes the shim to be included in the program.
The original `referencedFiles` array is saved and restored after program
creation, hiding this little hack from the rest of the system.

The new shim generation engine differentiates between two kinds of shims:
top-level shims (such as the flat module entrypoint file and
__ng_typecheck__.ts) and per-file shims such as ngfactory or ngsummary
files. The former are included via `rootFiles` as before, the latter are
included via the `referencedFiles` of their corresponding original files.

As a result of this change, shims are now correctly generated for all files
in the program, not just the ones named in `tsconfig.json`.

A few mitigating factors prevented this bug from being realized until now:

* in g3, `files` does include the transitive closure of files in the program
* in CLI apps, shims are not really used

This change also makes use of a novel technique for associating information
with source files: the use of an `NgExtension` `Symbol` to patch the
information directly onto the AST object. This is used in several
circumstances:

* For shims, metadata about a `ts.SourceFile`'s status as a shim and its
  origins are held in the extension data.
* For original files, the original `referencedFiles` are stashed in the
  extension data for later restoration.

The main benefit of this technique is a lot less bookkeeping around `Map`s
of `ts.SourceFile`s to various kinds of data, which need to be tracked/
invalidated as part of incremental builds.

This technique is based on designs used internally in the TypeScript
compiler and is serving as a prototype of this design in ngtsc. If it works
well, it could have benefits across the rest of the compiler.

PR Close #36211
2020-05-05 18:40:42 -07:00
.circleci build: remove typescript 3.6 and 3.7 support (#36329) 2020-05-05 16:52:43 -07:00
.devcontainer build: update the recommended `Dockerfile` for VSCode remote development (#34697) 2020-01-09 13:31:14 -08:00
.github fix(dev-infra): do not run the `lock-closed` GitHub action on forks (#36000) 2020-03-11 14:45:47 -04:00
.vscode build: fix @bazel/bazel to bazelisk leftovers (#36132) 2020-03-19 08:58:47 -07:00
.yarn build: update to latest version of yarn (#36464) 2020-04-14 12:47:30 -07:00
aio refactor(docs-infra): take advantage of latest Jasmine features in preview server tests (#36837) 2020-05-05 17:46:46 -07:00
dev-infra build: migrate bazel related formatting/linting to ng-dev format (#36842) 2020-05-04 12:45:00 -07:00
docs feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
goldens feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
integration feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
modules feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
packages fix(compiler): switch to 'referencedFiles' for shim generation (#36211) 2020-05-05 18:40:42 -07:00
scripts build: update dependencies to use typescript 3.8 and angular 9.1 (#36329) 2020-05-05 16:52:43 -07:00
third_party ci: Remove old vendoring solution in favor of relying on yarn-path (#35083) 2020-02-06 15:30:51 -08:00
tools build: remove typescript 3.6 and 3.7 support (#36329) 2020-05-05 16:52:43 -07:00
.bazelignore build: add npm package manifest to npm_integration_test (#35669) 2020-02-26 12:58:35 -08:00
.bazelrc build: do not build runfile trees unnecessarily (#36914) 2020-05-05 12:00:04 -07:00
.bazelversion build: depend on bazelisk rather than directly on Bazel (#36078) 2020-03-16 10:58:06 -07:00
.clang-format feat(tooling): Add a .clang-format for automated JavaScript formatting. 2015-04-02 08:44:34 -07:00
.dev-infra.json build: migrate bazel related formatting/linting to ng-dev format (#36842) 2020-05-04 12:45:00 -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 ci: do not run benchmark measurements in circleci (#34753) 2020-01-29 09:22:27 -08: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 build: fix typo in PullApprove group name (server-worker --> service-worker) (#36325) 2020-05-05 17:46:06 -07:00
.yarnrc build: update to latest version of yarn (#36464) 2020-04-14 12:47:30 -07:00
BUILD.bazel revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798) 2020-04-24 11:03:38 -07:00
CHANGELOG.md release: cut the v10.0.0-next.5 release 2020-05-04 14:48:09 -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(dev-infra): update triage and contributing docs for dev-infra (#35995) 2020-03-10 21:02:17 -04:00
LICENSE build: bump year (#34651) 2020-01-13 07:21:43 -08:00
README.md docs: remove browserstack badge from readme (#35684) 2020-03-17 09:29:43 -07:00
WORKSPACE revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798) 2020-04-24 11:03:38 -07:00
browser-providers.conf.js ci: update the browser test matrix to match supported browsers (#35202) 2020-02-14 11:14:05 -08:00
gulpfile.js build: migrate from gulp to ng-dev for running formatting (#36726) 2020-04-24 12:32:18 -07:00
karma-js.conf.js ci: ensure saucelabs browsers can load karma test page (#35171) 2020-02-06 15:36:27 -08:00
package.json build: update dependencies to use typescript 3.8 and angular 9.1 (#36329) 2020-05-05 16:52:43 -07:00
protractor-perf.conf.js revert: "feat(dev-infra): exposed new rule 'component_benchmark' via dev_infra (#36434)" (#36798) 2020-04-24 11:03:38 -07:00
shims_for_IE.js Revert "refactor: add license header to JS files & format files (#12035)" 2016-10-04 14:06:41 -07:00
test-events.js refactor: rename unpatched event flag in Zone from `BLACK_LISTED_EVENTS` to `UNPATCHED_EVENTS` (#29617) 2019-10-04 08:44:58 -07:00
test-main.js feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
tslint.json feat: remove @angular/http (#27038) 2020-05-05 17:42:01 -07:00
yarn.lock build: update dependencies to use typescript 3.8 and angular 9.1 (#36329) 2020-05-05 16:52:43 -07:00
yarn.lock.readme.md build: remove travisci leftovers (#27979) 2019-01-09 10:41:16 -08:00

README.md

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.