Updates the compiler-cli compliance goldens. The golden updates are
required due to a regression in TypeScript 4.3 that causes the emitter
to not incorrectly preserve lines when emitting a node list.
This can be reverted once https://github.com/microsoft/TypeScript/pull/44070
is available.
PR Close#42022
Currently we support safe property (`a?.b`) and method (`a?.b()`) accesses, but we don't handle safe keyed reads (`a?.[0]`) which is inconsistent. These changes expand the compiler in order to support safe key read expressions as well.
PR Close#41911
This is follow-up from #41437 and it reduces the amount of code we generate for safe property accesses (`a?.b`) and nullish coalescing (`a ?? b`) by:
1. Reusing variables in nested nullish coalescing expressions.
2. Not initializing temporary variables to `null`. The way our code is generated means that the value will always be overwritten before we compare against it so the initializer didn't really matter.
Fixes#41491.
PR Close#41563
Previously, it was not possible to block a partial-linker from trying to
process a declaration that was defined in a newer version of Angular than
that of the partial-linker. For example, if a partial-linker was published as
part of version 12.0.0, there was no way for a partially-compiled declaration
compiled via version 13.0.0 to tell the 12.0.0 linker that it would be invalid
to attempt to process it.
This commit adds a new `minVersion` property to partial-declarations, which is
interpreted as the "minimum partial-linker version" that can process this
declaration. When selecting a partial-linker for such a declaration, the known
linker version ranges are checked to find the most recent linker whose version
range has an overlap with the interpreted declaration range.
This approach allows us to set a minimum version for a declaration, which
can inform an old partial-linker that will it not be able to accurately
process the declaration.
Note that any pre-release part to versions are ignored in this selection
process.
The file-linker can be configured, via the `unknownDeclarationVersionHandling`
property of `LinkerOptions`, to handle such a situation in one of three ways:
- `error` - the version mismatch is a fatal error
- `warn` - a warning is sent to the logger but the most recent partial-linker
will attempt to process the declaration anyway.
- `ignore` - the most recent partial-linker will, silently, attempt to process
the declaration.
The default is to throw an error.
Closes#41497
PR Close#41578
This commit refactors the generated code for class metadata in partial
compilation mode. Instead of emitting class metadata into a top-level
`ɵsetClassMetadata` call guarded by `ngDevMode` flags, the class
metadata is now declared using a top-level `ɵɵngDeclareClassMetadata`
call.
PR Close#41200
This commit changes the partial compilation so that it outputs declaration
calls rather than compiled factory functions.
The JIT compiler and the linker are updated to be able to handle these
new declarations.
PR Close#41231
The `ɵɵInjectorDef` interface is internal and should not be published publicly
as part of libraries. This commit updates the compiler to render an opaque
type, `ɵɵInjectorDeclaration`, for this instead, which appears in the typings
for compiled libraries.
PR Close#41119
Th `ɵɵFactoryDef` type will appear in published libraries, via their typings
files, to describe what type dependencies a DI factory has. The parameters
on this type are used by tooling such as the Language Service to understand
the DI dependencies of the class being created by the factory.
This commit moves the type to the `public_definitions.ts` file alongside
the other types that have a similar role, and it renames it to `ɵɵFactoryDeclaration`
to align it with the other declaration types such as `ɵɵDirectiveDeclaration`
and so on.
PR Close#41119
These types are only used in the generated typings files to provide
information to the Angular compiler in order that it can compile code
in downstream libraries and applications.
This commit aliases these types to `unknown` to avoid exposing the
previous alias types such as `ɵɵDirectiveDef`, which are internal to
the compiler.
PR Close#41119
The partial declaration of a component includes the list of directives
that are used in its template, including some metadata of the directive
which can be used during actual compilation of the component. Used
components are currently part of this list, as components are also
directives. This commit splits the used components into a dedicate
property in the partial declaration, which allows for template
compilation to optimize the generated code for components.
PR Close#41104
This commit changes the partial compilation so that it outputs declaration
calls rather than definition calls for NgModules and Injectors.
The JIT compiler and the linker are updated to be able to handle these
new declarations.
PR Close#41080
Previously, injector definitions contained a `factory` property that
was used to create a new instance of the associated NgModule class.
Now this factory has been moved to its own `ɵfac` static property on the
NgModule class itself. This is inline with how directives, components and
pipes are created.
There is a small size increase to bundle sizes for each NgModule class,
because the `ɵfac` takes up a bit more space:
Before:
```js
let a = (() => {
class n {}
return n.\u0275mod = c.Cb({type: n}),
n.\u0275inj = c.Bb({factory: function(t) { return new (t || n) }, imports: [[e.a.forChild(s)], e.a]}),
n
})(),
```
After:
```js
let a = (() => {
class n {}
return n.\u0275fac = function(t) { return new (t || n) },
n.\u0275mod = c.Cb({type: n}),
n.\u0275inj = c.Bb({imports: [[r.a.forChild(s)], r.a]}),
n
})(),
```
In other words `n.\u0275fac = ` is longer than `factory: ` (by 5 characters)
and only because the tooling insists on encoding `ɵ` as `\u0275`.
This can be mitigated in a future PR by only generating the `ɵfac` property
if it is actually needed.
PR Close#41022
This change marks all relevant define* callsites as pure, causing the compiler to
emmit either @__PURE__ or @pureOrBreakMyCode annotation based on whether we are
compiling code annotated for closure or terser.
This change is needed in g3 where we don't run build optimizer but we
need the code to be annotated for the closure compiler.
Additionally this change allows for simplification of CLI and build optimizer as they
will no longer need to rewrite the generated code (there are still other places where
a build optimizer rewrite will be necessary so we can't remove it, we can only simplify it).
PR Close#41096
The `template` and `isInline` fields were previously stored in a nested
object, which was initially done to accommodate for additional template
information to support accurate source maps for external templates. In
the meantime the source mapping has been accomplished in a different
way, and I feel this flattened structure is simpler and smaller so is
preferable over the nested object. This change also makes the `isInline`
property optional with a default value of `false`.
PR Close#40383
The types of directives and pipes that are used in a component's
template may be emitted into the partial declaration wrapped inside a
closure, which is needed when the type is declared later in the module.
This poses a problem for JIT compilation of partial declarations, as
this closure is indistinguishable from a class reference itself. To mark
the forward reference function as such, this commit changes the partial
declaration codegen to emit a `forwardRef` invocation wrapped around
the closure, which ensures that the closure is properly tagged as a
forward reference. This allows the forward reference to be treated as
such during JIT compilation.
PR Close#40117
Prior to this change, the `setClassMetadata` call would be invoked
inside of an IIFE that was marked as pure. This allows the call to be
tree-shaken away in production builds, as the `setClassMetadata` call
is only present to make the original class metadata available to the
testing infrastructure. The pure marker is problematic, though, as the
`setClassMetadata` call does in fact have the side-effect of assigning
the metadata into class properties. This has worked under the assumption
that only build optimization tools perform tree-shaking, however modern
bundlers are also able to elide calls that have been marked pure so this
assumption does no longer hold. Instead, an `ngDevMode` guard is used
which still allows the call to be elided but only by tooling that is
configured to consider `ngDevMode` as constant `false` value.
PR Close#39987
A couple reasons to justify removing the flag:
* It adds code to the compiler that is only meant to support test cases
and not any production. We should avoid code in that's only
meant to support tests.
* The flag enables writing tests that do not mimic real-world behavior
because they allow invalid applications
PR Close#40013
The partial compiler will add a version number to the objects that are
generated so that the linker can select the appropriate partial linker
class to process the metadata.
Previously this version matching was a simple number check. Now
the partial compilation writes the current Angular compiler version
into the generated metadata, and semantic version ranges are used
to select the appropriate partial linker.
PR Close#39847
This commit implements partial compilation of components, together with
linking the partial declaration into its full AOT output.
This commit does not yet enable accurate source maps into external
templates. This requires additional work to account for escape sequences
which is non-trivial. Inline templates that were represented using a
string or template literal are transplated into the partial declaration
output, so their source maps should be accurate. Note, however, that
the accuracy of source maps is not currently verified in tests; this is
also left as future work.
The golden files of partial compilation output have been updated to
reflect the generated code for components. Please note that the current
output should not yet be considered stable.
PR Close#39707
The JSON schema reference was off-by-one, preventing IDEs from finding
the file and offering suggestions and documentation. Additionally the
name of the golden file was slightly off.
PR Close#39707
This commit contains the basic runner logic and a couple of sample test cases
for the "full compile" compliance tests, where source files are compiled
to full definitions and checked against expectations.
PR Close#39617