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
Showing
- packages/compiler-cli/src/ngtsc/core/BUILD.bazel 1 addition, 0 deletionspackages/compiler-cli/src/ngtsc/core/BUILD.bazel
- packages/compiler-cli/src/ngtsc/core/src/compiler.ts 3 additions, 6 deletionspackages/compiler-cli/src/ngtsc/core/src/compiler.ts
- packages/compiler-cli/src/ngtsc/core/src/host.ts 79 additions, 63 deletionspackages/compiler-cli/src/ngtsc/core/src/host.ts
- packages/compiler-cli/src/ngtsc/core/test/compiler_test.ts 1 addition, 1 deletionpackages/compiler-cli/src/ngtsc/core/test/compiler_test.ts
- packages/compiler-cli/src/ngtsc/core/test/host_spec.ts 52 additions, 0 deletionspackages/compiler-cli/src/ngtsc/core/test/host_spec.ts
- packages/compiler-cli/src/ngtsc/entry_point/src/generator.ts 4 additions, 7 deletionspackages/compiler-cli/src/ngtsc/entry_point/src/generator.ts
- packages/compiler-cli/src/ngtsc/program.ts 4 additions, 2 deletionspackages/compiler-cli/src/ngtsc/program.ts
- packages/compiler-cli/src/ngtsc/shims/BUILD.bazel 10 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/BUILD.bazel
- packages/compiler-cli/src/ngtsc/shims/README.md 76 additions, 3 deletionspackages/compiler-cli/src/ngtsc/shims/README.md
- packages/compiler-cli/src/ngtsc/shims/api.ts 51 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/api.ts
- packages/compiler-cli/src/ngtsc/shims/index.ts 5 additions, 4 deletionspackages/compiler-cli/src/ngtsc/shims/index.ts
- packages/compiler-cli/src/ngtsc/shims/src/adapter.ts 229 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/src/adapter.ts
- packages/compiler-cli/src/ngtsc/shims/src/api.ts 0 additions, 27 deletionspackages/compiler-cli/src/ngtsc/shims/src/api.ts
- packages/compiler-cli/src/ngtsc/shims/src/expando.ts 102 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/src/expando.ts
- packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts 39 additions, 39 deletions...ges/compiler-cli/src/ngtsc/shims/src/factory_generator.ts
- packages/compiler-cli/src/ngtsc/shims/src/factory_tracker.ts 0 additions, 38 deletionspackages/compiler-cli/src/ngtsc/shims/src/factory_tracker.ts
- packages/compiler-cli/src/ngtsc/shims/src/reference_tagger.ts 83 additions, 0 deletions...ages/compiler-cli/src/ngtsc/shims/src/reference_tagger.ts
- packages/compiler-cli/src/ngtsc/shims/src/summary_generator.ts 11 additions, 36 deletions...ges/compiler-cli/src/ngtsc/shims/src/summary_generator.ts
- packages/compiler-cli/src/ngtsc/shims/src/util.ts 11 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/src/util.ts
- packages/compiler-cli/src/ngtsc/shims/test/BUILD.bazel 4 additions, 0 deletionspackages/compiler-cli/src/ngtsc/shims/test/BUILD.bazel
Please register or sign in to comment