Commit graph

1727 commits

Author SHA1 Message Date
Paul Gschwendtner
f8c02b69b9 refactor(compiler-cli): restrict read option values for signal-based queries (#54257)
The `read` option for queries can rely on lexical variables inside the
class. These constructs are fine from a technical perspective in
TypeScript, but in practice, when the component/directive definition is
being created, the read value is extracted into the definition,
**outside** of the class. This breaks `this` references.

To fix this, we are restricting the `read` option to literal values.
Similar to `descendants`. Literal references are in practice constructs
like:

 - `read: bla.X`
 - `read: X`

 where `bla` or `X` is never a `ThisKeywoord`- hence fixing the issue
 and also simplifying the patterns for easier single file compilation.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner
902481b6ec refactor(compiler-cli): add JIT transform for signal-based queries (#54257)
This commit adds a JIT transform for signal-based queries, so that
queries are working as expected in JIT environments like `ng test` where
decorator metadata is needed as a prerequisite for the component
definition creation.

This is similar to the JIT transforms for signal inputs etc.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner
351426853d refactor(compiler-cli): extract common JIT transform helper into transform API (#54257)
Extracts common JIT transform helper into the transform API, so that
those helpers can be re-used for output, model, queries and inputs.

PR Close #54257
2024-02-06 16:04:10 +00:00
Paul Gschwendtner
1d077fca10 refactor(compiler-cli): expose query function detection logic for JIT transform (#54257)
This commit exposes the query function detection logic so that it can
be used in the JIT transform later on.

PR Close #54257
2024-02-06 16:04:10 +00:00
Jessica Janiuk
e46c08170f Revert "fix(compiler-cli): consider the case of duplicate Angular decorators in local compilation diagnostics (#54139)" (#54264)
This reverts commit 4b1d948b36.

PR Close #54264
2024-02-05 18:18:47 +00:00
Jessica Janiuk
bd43aa39a8 Revert "fix(compiler-cli): allow custom/duplicate decorators for @Injectable classes in local compilation mode (#54139)" (#54264)
This reverts commit a592904c69.

PR Close #54264
2024-02-05 18:18:47 +00:00
Jessica Janiuk
a2af706855 Revert "fix(compiler-cli): forbid custom/duplicate decorator when option forbidOrphanComponents is set (#54139)" (#54264)
This reverts commit 96bcf4fb12.

PR Close #54264
2024-02-05 18:18:47 +00:00
Paul Gschwendtner
b285b1402c refactor(compiler-cli): introduce JIT transform for new output() initializer API (#54217)
Similar to `input()`, initializer-based `output()`'s need to be
transformed in JIT to be annotated with an `@Output()` decorator.

This is necessary so that Angular can statically collect all defined
outputs without instantiating the class (which would not be possible
upon directive definition computation).

This commit introduces a transform next to the input transform that
automatically runs with the Angular CLI and `ng test`.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner
55040fb80b test: add type check diagnostic tests for output() API (#54217)
Adds type check diagnostic tests for the `output()` API. This
is necessary because we are maintaining a separate emitter
for `output()` as with the current design (still discussed - but this is
a starting foundation).

Note: `OutputEmitter` currently does not publicly expose `.subscribe`,
while the testing infrastructure exposes it for now. That is because we
are still discussing this before making changes in the TCB to account
for the case where `.subscribe` might be `@internal` ultimately.

PR Close #54217
2024-02-05 15:08:35 +00:00
Paul Gschwendtner
0e9e401ca1 test: generalize type check scenario testing helpers (#54217)
Generalizes the type check table scenario testing infrastructure
so that it can also be used for testing outputs in a table-scheme
without a lot of TS code repetition.

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner
65de61ba0d test: add compliance output tests for output() (#54217)
Adds compliance output tests for `output()` to verify that
we are emitting proper full compilation output, as well as proper
partial compilation output that can be linked to match the full output.

PR Close #54217
2024-02-05 15:08:34 +00:00
Paul Gschwendtner
f7da77b90d refactor(compiler-cli): detect output() function (#54217)
As we are introducing the new `output()` function as an inituive
alternative to `@Output()` that matches with signal-based inputs,
this commit prepares the compiler to detect such initializer-based
outputs.

PR Close #54217
2024-02-05 15:08:34 +00:00
Payam Valadkhan
96bcf4fb12 fix(compiler-cli): forbid custom/duplicate decorator when option forbidOrphanComponents is set (#54139)
The deps tracker which is responsible to track orphan components does not work for classes mutated by custom decorator. Some work needed to make this happen (tracked in b/320536434). As a result, with option `forbidOrphanComponents` being true the deps tracker will falsely report any component as orphan if it or its NgModule have custom/duplicate decorators. So it is unsafe to use this option in the presence of custom/duplicate decorator and we disable it until it is made compatible. Note that applying custom/duplicate decorators to `@Injectable` classes is ok since these classes never make it into the deps tracker. So we excempt them.

PR Close #54139
2024-02-05 15:07:40 +00:00
Payam Valadkhan
a592904c69 fix(compiler-cli): allow custom/duplicate decorators for @Injectable classes in local compilation mode (#54139)
Custom/duplicate decorators break the deps tracker in local mode. But deps tracker only deals with non-injectable classes. So applying custom/duplicate decorators to `@Injectable` only classes does not disturb deps tracker and local compilation in general. There are also ~ 100 such cases in g3 which cannot be cleaned up.

PR Close #54139
2024-02-05 15:07:40 +00:00
Payam Valadkhan
4b1d948b36 fix(compiler-cli): consider the case of duplicate Angular decorators in local compilation diagnostics (#54139)
For cases like this:

```
@Component({...})
@Component({...})
export class SomeComp {
}
```

The `DecoratorHandler.detect` apparantly matches only one of the `@Component` decorator, leaving the other undetected which will be transformed by TS decorator helper and that breaks local compilation runtimes. But the error message only mentioned "custom" decorator, while in this case it is a "duplicate Angular" decorator. The respective error message is updated thus.

PR Close #54139
2024-02-05 15:07:40 +00:00
Paul Gschwendtner
d74ee6e343 refactor(compiler-cli): group initializer-API based transforms into single transform (#54200)
Instead of maintaining individual transforms for `input`, `output`,
`model` etc. we are grouping them directly and the first one matching,
will execute.

This reduces needed traversal through AST and also makes it a little
more clean to write new initializer API metadata transforms.

Note: The Angular JIT transform is now also moving from `tooling.ts`
directly into `/transformers` for more local placement of transformer
logic.

PR Close #54200
2024-02-01 15:58:50 +00:00
Kristiyan Kostadinov
d89d5230a7 refactor(compiler-cli): allow signal input transform to be reused (#54200)
Splits up the signal input transform so that it can be reused for other signal-based properties.

PR Close #54200
2024-02-01 15:58:50 +00:00
Kristiyan Kostadinov
95dcf5fafa fix(compiler-cli): handle default imports in defer blocks (#53695)
Fixes that `@defer` blocks weren't recognizing default imports and generating the proper code for them. Default symbols need to be accessed through the `default` property in the `import` statement, rather than by their name.

PR Close #53695
2024-02-01 15:58:21 +00:00
Payam Valadkhan
64fa5715c6 fix(compiler-cli): generating extra imports in local compilation mode when cycle is introduced (#53543)
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
7e861c640e feat(compiler-cli): generate extra imports for component local dependencies in local mode (#53543)
With option `generateExtraImportsInLocalMode` set, in local mode the compiler generates extra imports for each component local dependencies. Here local dependencies means all component's dependencies within the same compilation unit.

To achieve this, the compiler performs a "local version" of its regular static analysis to find each component's deps, and these deps are used to generate extra side effect imports.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
f6e9dbbe73 refactor(compiler-cli): run resolve phase fully for components in local mode when generateExtraImportsInLocalMode is set (#53543)
In this commit the resolve method for components is run fully when the option `generateExtraImportsInLocalMode` is set. This is because we need local component depedencies in order to generate extra imports causing by them. This requires cutting some resolve phase logics that are unnecessary in local mode, such as diagnostics.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
6a136d1ab3 refactor(compiler-cli): run register phase in local compilation mode (#53543)
When option `generateExtraImportsInLocalMode` is set, we need to compute component local depednecies in order to generate extra imports related to them. At the same time running the register phase in general is harmless in local compilation. So we run it anyway.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
3263df23f2 feat(compiler-cli): generate global imports in local compilation mode (#53543)
With option `generateExtraImportsInLocalMode` set in local compilation mode, the compiler generates extra side effect imports using this rule: any external module from which an identifier is imported into an NgModule will be added as side effect import to every file in the compilation unit. To illustrate this better assume the compilation unit has source files `a.ts` and `b.ts`, and:

```
// a.ts
import {SomeExternalStuff} from 'path/to/some_where';
import {SomeExternalStuff2} from 'path/to/some_where2';

...

@NgModule({imports: [SomeExternalStuff]})

```

then the extra import `import "path/to/some_where"` will be added to both `a.js` and `b.js`. Note that this is not the case for `import "path/to/some_where2"` though, since the symbol `SomeExternalStuff2` is not imported into any NgModule.

The math behind this mechanism is, in local compilation mode we cannot resolve component external dependencies fully. For example if a component in `a.ts` uses an external component defined in an external file `some_external_comp.ts` then we can generate the import to this file in `a.js`. Instead, we want to generate an import to a file that "gurantees" that `a.js` is placed after `some_external_comp.js` in the bundle. Now since the component in  `some_external_comp.ts` is used in `a.ts`, then there must be a chain of imports starting from the NgModule that declares the component in `a.ts` to the component in `some_external_comp.ts`. This chain means some file in the same compilation unit as `a.ts` should import some external NgModule which includes `some_external_comp.ts` in its transitive closure and import it to some NgModule. So by adding this import to `a.js` we ensure that the bundling will have the right order.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
8c36f2d6f1 refactor(compiler-cli): ability to generate side effect imports (#53543)
As the first step,  the import manager's `generateSideEffectImport` method is implemented to enable it to store info for side effect imports. Next, the helper `addImports` is modified to be able to generate correct statement for side effect imports.

These changes will be tested in the subsequent commits when these tools are used to generate an actual extra import for the generated file.

PR Close #53543
2024-01-30 15:05:42 +00:00
Payam Valadkhan
fc55de1416 refactor(compiler-cli): incorporate LocalCompilationExtraImportsTracker in the compilation workflow (#53543)
This commit includes a skeleton of how the tool `LocalCompilationExtraImportsTracker` is used in the overall compilation workflow end-to-end.

First of all, a new option `generateExtraImportsInLocalMode` is added, whose presence will make `LocalCompilationExtraImportsTracker` part of the compilation process. When this option is set an instance of `LocalCompilationExtraImportsTracker` is created within the NgCompiler. Then it is passed to the Ivy transformer and plumbed all the way down and the extra imports registered in it are added to the `ImportManager` instances before the imports are added from `ImportManager` to the generated file. This required adding a new method `generateSideEffectImport` to the `ImportManager`, which is an empty method and will be implemented in the subsequent commits.

This commit expected to make no change in the compilation behavior as the methods are not implemented yet.

PR Close #53543
2024-01-30 15:05:42 +00:00
Payam Valadkhan
ac3c484bb1 refactor(compiler-cli): add API for extra import tracker (#53543)
The tracker is responsible for registering the extra imports during the analysis and resolve compiler phases, and later to be used by the transformer to get a list of extra imports to be generated for each source file.

This commit only contains the API, and the actual implementation for each method will be done in subsequent commits where an application of that method is available and so tests can be written for the implementation.

PR Close #53543
2024-01-30 15:05:42 +00:00
Dylan Hunn
7b4d275f49 fix(compiler): Fix the template pipeline option (#54148)
The `useTemplatePipeline` option was not properly threaded through the component handler.

PR Close #54148
2024-01-29 21:12:32 +00:00
Payam Valadkhan
0970129e20 fix(compiler-cli): show proper error for custom decorators in local compilation mode (#53983)
At the moment local compilation mode does not support custom decorators, and it leads to unhandled errors. In this change a compile time diagnostic is produced in local mode for custom decorators. This is a temporary solution since there are few custom decorators are in use in g3. Custom decorators will be eventually supported in local mode.

PR Close #53983
2024-01-26 19:11:34 +00:00
Paul Gschwendtner
fe4343cf13 refactor(compiler): extract call and construct signatures of interfaces (#54053)
This adds initial support for extracting and rendering call and construct
signatures of classes, like within the new `InputFunction` for signal
inputs.

For now, signatures are a rare occasion and represented as class member
entries. In the future we might consider exposing this via its own entry
type, and field on the class/interface entry.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner
58b8a232d6 fix(compiler-cli): support jumping to definitions of signal-based inputs (#54053)
This fixes the definitions for signal-based inputs in the language
service and type checking symbol builder.

Signal inputs emit a slightly different output. The output works well
for comppletion and was designed to affect language service minimally.
Turns out there is a small adjustment needed for the definition symbols.

PR Close #54053
2024-01-26 19:10:56 +00:00
Paul Gschwendtner
b78042f3a5 refactor(core): separate InputSignal and InputSignalWithTransform (#54053)
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.

Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.

For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.

A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.

PR Close #54053
2024-01-26 19:10:56 +00:00
Kristiyan Kostadinov
93188cb439 refactor(compiler): distinguish two-way bindings in the AST (#54065)
During the template parsing stage two-way bindings are split up into a property and event binding. All the downstream code treats these binding the same as their one-way equivalents. For some future work we'll have to distinguish between the two so these changes update the `BoundElementProperty.type` and `ParsedEvent.type` to include a `TwoWay` type. All existing call-sites have been updated to treat `TwoWay` the same as `Property`/`Regular`, but more specialized logic will be added in the future.

PR Close #54065
2024-01-25 16:31:57 +00:00
Andrew Scott
eddf5dae5e fix(compiler): Update type check block to fix control flow source mappings (#53980)
The source mappings and types for various pieces of the control flow
were not quite right and prevented the language service from providing
accurate information.

fixes https://github.com/angular/vscode-ng-language-service/issues/1988

PR Close #53980
2024-01-24 18:37:58 -05:00
Dylan Hunn
47e6e84101 feat(compiler): Add a TSConfig option useTemplatePipeline (#54057)
The Template Pipeline is a brand new backend for the Angular compiler, replacing `TemplateDefinitionBuilder`. It generates the Ivy instructions corresponding to an input template (or host binding). The Template Pipeline has an all-new design based on an intermediate representation compiled over many phases, which will allow us to experiment with compiler changes more easily in the future.

With this commit, the template pipeline can now be enabled in any project via the `useTemplatePipeline` TSConfig option. However, it is still disabled by default.

PR Close #54057
2024-01-24 18:36:23 -05:00
Paul Gschwendtner
17a47c4c54 refactor(compiler-cli): additional diagnostics for signal-based queries (#54019)
This commit introduces three additional diagnostics for queries:

- If a query (either using decorator or signal-based) is declared on a
  static class member, a diagnostic is raised.
- If a signal-based query is mixed with a query decorator, a diagnostic
  is raised. Similar to signal inputs.
- If a singal-based query is also declared in the directive/component
  class decorator metadata, a diagnostic is raised.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner
a7017a0471 refactor(core): improve safety of input/query initializer API detection (#54019)
Due to some refactorings, we were only checking the function name
and whether it originates from an import. We should also verify the
module. This seems like logic we lost in the refactorings.

PR Close #54019
2024-01-24 16:13:31 +01:00
Andrew Kushnir
aeaec8629c refactor(compiler-cli): rephrase an error message related to @defer and local compilation (#54030)
This commit updates the error message to cover cases when imported symbols have eager references inside of a file.

PR Close #54030
2024-01-24 10:08:50 +01:00
Paul Gschwendtner
d4c84a97e8 refactor(compiler-cli): generate partial compilation output for signal-based queries (#53978)
This commit ensures that libraries can use signal-based queries, and the
partial compilation output will capture their metadata.

The linker is updated to support parsing this.

Two notes:

1. Older linker versions are not capable of parsing this, so the minimum
   version for signal-based queries is adjusted when such are used.
2. We only emit `isSignal` metadata for queries when signal queries are
   used. This enables libraries to continue supporting older linker
   versions, if signal-based queries are not used.

PR Close #53978
2024-01-23 10:24:36 +01:00
Paul Gschwendtner
df828e9947 test: add compiler integration test for signal-based queries (#53978)
Adds a compiler integration test for recognizing signal-based queries,
and emitting the expected output. Concrete output will be verified via
the compliance tests.

PR Close #53978
2024-01-23 10:24:36 +01:00
Paul Gschwendtner
8f936a4111 refactor(compiler-cli): recognize signal-based queries in class initializers (#53978)
This commit uses the initializer API recognition that we built for
signal-based inputs, and teaches the compiler to recognize class members
that refer to `viewChild`, `viewChildren`, `contentChild` or
`contentChildren`. Those will declare signal-based view or content queries.

PR Close #53978
2024-01-23 10:24:36 +01:00
Paul Gschwendtner
7ed3927082 refactor(compiler-cli): expose helper for recognizing initializer APIs (#53978)
The new `input` API is recognized using class member initializers.
We want to support similar APIs for queries, using e.g. `viewChild`
or `viewChild.required`.

This commit extracts the input recognition API and makes it reusable,
so that the same logic can be used to detect queries on a class member.

Additional changes:
  - replacing `coreModule` with the simpler `isCore` parameter. This is
    more readable.
  - support for detecting a list of API names on a single class member.
    This allows us to detect possible query functions on the same class
    member without having to check X times. We simply check for the
    initializer API pattern and check if one API function name matches.

PR Close #53978
2024-01-23 10:24:36 +01:00
Payam Valadkhan
3e1384048e feat(compiler-cli): support host directives for local compilation mode (#53877)
At the moment local compilation breaks for host directives because the current logic relies on global static analysis. This change creates a local version by cutting the diagnostics and copying the directive identifier as it is to the generated code without attempting to statically resolve it.

PR Close #53877
2024-01-22 14:44:24 +01:00
Payam Valadkhan
b774e22d8e feat(compiler-cli): make it configurable to generate alias reexports (#53937)
At the moment when unified host is selected (through option `_useHostForImportGeneration`) the compiler always generates alias reexports. Such reexports are mainly generated to satisfy strict dependency condition for generated files. Such condition is no longer the case for G3. At the same time, these alias reexports make it impossible to mix locally compiled targets with globally compiled targets. More precisely, a globally compiled target may not be able to consume a locally compiled target as its dependency since the former may import from the alias reexports which do not exist in the latter due to local compilation mode. So, to make global-local compilation interop possible, it is required to be able to turn off alias reexport generation.

PR Close #53937
2024-01-22 14:20:26 +01:00
cexbrayat
a7f8d9dc08 refactor(compiler-cli): interpolatedSignalNotInvoked diagnostic for input signals (#53883)
This updates the extended diagnotic to handle input signals as well.

PR Close #53883
2024-01-17 11:36:43 -08:00
Andrew Kushnir
b0e0f0014e refactor(compiler): extra diagnostics for @defer in local compilation mode (#53899)
This commit adds extra logic to produce a diagnostic in case `@Component.deferredImports` contain types from imports that also bring eager symbols. This would result in retaining a regular import and generating a dynamic import, which would not allow to defer-load dependencies.

PR Close #53899
2024-01-17 10:46:15 -08:00
Andrew Kushnir
08233b8374 refactor(compiler): enable register and resolve phases for local compilation (#53901)
This commit update the logic to enable `register` and `resolve` phases for local compilation. Those phases will be useful for local compilation in certain cases (will be used in followup PRs).

PR Close #53901
2024-01-17 09:03:55 -08:00
Paul Gschwendtner
760b1f3d0b fix(compiler-cli): do not throw fatal error if extended type check fails (#53896)
Currently when the extended type check fails due to an import reference
that cannot be generated, the fatal diagnostic is not caught and
not properly exposed as a `ts.Diagnostic` that can be gracefully
handled. This is inconsistent to non-extended type checking diagnostics.

This is problematic because Angular CLI applications currently fail in
obscure ways because:

- the CLI does not expect `getDiagnosticsForFile` to actually throw
  runtime errors.
- the CLI does not seem to properly print these errors given the
  parallel workers and build excection, and those errors are
  especially hard to debug because there is no `stack` for
  `FatalDiagnosticError`'s.

Example: `MyDir` is not exported and the type check block cannot reference it.

PR Close #53896
2024-01-16 09:36:36 -08:00
Andrew Kushnir
df685ed7c5 refactor(compiler-cli): add checks to prevent same deps in imports and deferredImports (#53591)
This commit updates the typechecker logic to prevent same deps in `imports` and `deferredImports`.

PR Close #53591
2024-01-10 15:28:58 -08:00
Andrew Kushnir
a2aa23d8b5 refactor(compiler): add support for internal deferredImports field (#53591)
This commit updates the logic to add support for internal `deferredImports` field in compiler.

PR Close #53591
2024-01-10 15:28:58 -08:00
Andrew Kushnir
b780d39612 refactor(compiler-cli): update DeferredSymbolTracker to use explicit deps config (#53591)
This commit updates the `DeferredSymbolTracker` class to take info account the `onlyExplicitDeferDependencyImports` flag. The `DeferredSymbolTracker` class also exposes a new API to register import declarations as explicitly deferred, which will be used in followup commits.

PR Close #53591
2024-01-10 15:28:58 -08:00