If a defer block is nested inside control flow while also being nested
underneath a defer block all using incremental hydration, timing issues
prevented the child nodes from being properly hydrated. This ensures
hydration happens on next render.
PR Close#58644
This commit is only useful to Google. It fixes that some code relies on
`readConfiguration`, but doesn't properly parse Angular compiler options
as those are part of `bazelOptions.angularCompilerOptions` if the
1P-generated tsconfig's are used.
PR Close#58637
A dot was appearing in the middle of the comment for `DerivedIsIncompatible`.
While at it, a dot was missing in `ClassManuallyInstantiated`.
PR Close#58636
In #57684 the standalone migration was changed so that it replaces any leftover modules with their `exports`, in an attempt to preserve more working code. These changes expand that logic to also cover tests since it's somewhat common internally to only import a component's module without having any references to the component.
Note that tests are a bit of a special case, because we don't have access to the template type checker, so instead we copy over all of the `exports` of that module.
PR Close#58627
Currently the `getPotentialImportsFor` only accepts a `ClassDeclaration` as the context for generating an import, but that's not necessary because it doesn't require any class-specific information. These changes expand it to any `Node` so that it can be used when generating imports in testing declarations.
PR Close#58627
Running `ng g @angular/core:signals` prompts for the question on which migration to run and offers 3 options (inputs, outputs, queries).
Running with `--defaults` skips the prompts, but only runs 2 of them.
This fixes it by including the `outputs` migration in the default ones.
PR Close#58635
Fixes an edge case where a control flow node that has non-projectable nodes followed by an element node at the end would cause the entire control flow node to be project. For example if we have a projection target of `Main: <ng-content/> Slot: <ng-content select="[foo]"/>`, inserting a node of `@if (true) {Hello <span foo>world</span>}` would project the entire `Hello world` into the `[foo]` slot.
In the process of working on the issue, I also found that `@let` declarations at the root of the control flow node would prevent content projection as well.
PR Close#58607
In this commit, we clean up the event contract once hydration is complete, which removes event
listeners registered through the container manager. If we do not clean up the contract, the listeners
will remain on the `document.body`. When incremental hydration is enabled, we cannot clean up the event
contract immediately; instead, we schedule its cleanup when the app is destroyed. This is because the
event contract is required for deferred blocks, of which we are unaware, that need to be hydrated.
PR Close#58174
This moves all the helpers out of the instructions file, keeping the instructions limited to the actual instruction set. This adds files for defer block rendering functions and triggering functions, respectively.
PR Close#58598
Initially the unused imports check was implemented so that it reports one diagnostic per component with the individual unused imports being highlighted through the `relatedInformation`. This works fine when reporting errors to the command line, but vscode appears to only show `relatedInformation` when the user hovers over a diagnostic which is a sub-par experience.
These changes switch to reporting a diagnostic for each unused import instead.
PR Close#58589
This commit improves the temporary variable generation in signal
migrations, whenever references are "shared" inside property
declarations.
PR Close#58581
Currently whenever we would come across a code snippet like this, where
`maxCellsPerRow` is an input, the control flow analysis would fall apart
because the first occurence of the node points to a control flow node
that is offset-wise "after" the first occurence. This commit makes the
logic more robust.
PR Close#58581
This cleans up the memory usage of the defer block registry and jsactionmap when a view is destroyed that contains a defer block that is not yet hydrated.
PR Close#58553
Previously we always ran Tsurge migrations with an Angular program, even
if it's a plain `ts_library` target. This has changed now, so we also
need to properly handle the case where a `ts_library` is analyzed, but
no Angular program is available.
PR Close#58541
Tsurge can run against the full Google3 depot, and will often also deal
with plain `ts_library` targets. Those shouldn't be constructed with the
Angular compiler as this could cause out of memory breakages etc. The
targets are simply not "proven" to be compatible with the Angular
compiler; so we shouldn't use them when not necessary.
PR Close#58541
Previously, `filterMethodOverloads` excluded all members without a body, causing issues with the extraction of functions and members in TypeScript types.
PR Close#58445
This commit utilizes the `@angular/ssr` NPM package to generate an API reference for its entry points using the `generate_api_docs` Bazel rule, which will be included in http://angular.dev/api.
PR Close#58445
The DOM renderer classes perform initialization that captures state from
the component definition during construction. To ensure that the state is
kept synchronized with any newly applied metadata from an HMR `applyMetadata`
call, each renderer is now recreated during the apply process. This also
allows inline component styles to be updated in cases where external component
stylesheets may not be viable.
PR Close#58527
This commit addresses a problem with tests that use the `fit` function to focus on individual test cases. While these tests run successfully in the full suite, they fail when focused individually using `fit`.
The issue lies in the behavior of `withEventReply` and other hydration-related functions (i.e., `provideX`, `withX`). These functions return platform-specific providers based on the `ngServerMode` setting, causing inconsistencies between server and browser environments. As a result, provider instances cannot be reused across server and browser applications.
**Example of problematic code:**
```ts
const hydrationFeatures = [withEventReply()];
const html = await ssr(SimpleComponent, { hydrationFeatures });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures,
});
// Expected behavior ...
```
**Solution:**
To address this, we define `hydrationFeatures` as a function instead of a static array. This ensures that a new instance of `withEventReply` is created separately for each environment, eliminating platform-specific mismatches between server and browser contexts:
```typescript
const hydrationFeatures = () => [withEventReply()]; // Define as a function
const html = await ssr(SimpleComponent, { hydrationFeatures: hydrationFeatures() });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures: hydrationFeatures(),
});
// Expected behavior ...
```
PR Close#58538
We were not properly passing around the TCB full program optimization,
so TCB generation was done per individual file. This significantly
slowed down reference resolution.
PR Close#58525
Currently when application source code references e.g. an NgModule that
points to references that aren't available, the compiler will break at
runtime without any actionable/reasonable error.
This could happen for example when a library is referenced in code, but
the library is simply not available in the `node_modules`. Clearly,
TypeScript would issue import diagnostics here, but the Angular compiler
shouldn't break fatally. This is useful for migrations which may run
against projects which aren't fully compilable. The compiler handles
this fine in all cases, except when processing `.d.ts` currently... and
the runtime exception invalides all other information of the program
etc.
This commit fixes this by degrading such unexpected cases for `.d.ts`
metadata reading to be handled gracefully. This matches existing logic
where the `.d.ts` doesn't necessarily match the "expecation"/"expected
format".
The worst case is that the Angular compiler will not have type
information for some directives of e.g. a library that just isn't
installed in local `node_modules`; compared to magical errors and
unexpected runtime behavior.
PR Close#58515
The use of relative imports vs. module imports and the existing mismatch
can cause symbols to be duplicated in migrations. This is problematic as
it breaks migration logic or compiler logic in the worst case.
Long-term we will solve this by having a better Bazel toolchain where
both relative and module imports can point to the same files; but in
practice this is not the case right now.
This commit fixes the fallback template logic in the signal
input/queries migration; in case no type check block information is
available.
PR Close#58515
When we check for duplicates in dev mode, we end up stringifying an `LView` even if we don't report an error. This can be expensive in large views.
These changes work around the issue by only generating the string when we have an error to throw.
Fixes#58509.
PR Close#58521
Angular components that use ShadowDOM view encapsulation have an alternate
execution path for adding component styles to the DOM that does not use the
SharedStylesHost that all other view encapsulation modes leverage. To ensure
that ShadowDOM components receive all defined styles, additional logic has been
added to the ShadowDOM specific renderer to also cover external styles.
PR Close#58482
When the compiler generates the `HostDirectivesFeature`, it generates either an eager call (`ɵɵHostDirectivesFeature([])`) or a lazy call (`ɵɵHostDirectivesFeature(() => [])`. The lazy call is necessary when there are forward references within the `hostDirectives` array. Currently we resolve the lazy variant when the component definition is created which has been enough for most cases, however if the host is injected by one of its host directives, we can run into a reference error because DI is synchronous and the host's class hasn't been defined yet.
These changes resolve the issue by pushing the lazy resolution later during directive matching when all classes are guanrateed to exist.
Fixes#58485.
PR Close#58492
Before v19, the default value of the standalone flag was false, this code change flips the logic in the migration to make it true by default.
PR Close#58474
Adjusts the HMR initialization to avoid the edge case where a developer makes change to a non-rendered component that exists in a lazy loaded chunk that has not been loaded yet. The changes include:
* Moving the `import` statement out into a separate function.
* Adding a null check for `d.default` before calling `replaceMEtadata`.
* Triggering the `import` callback eagerly on initialization.
Example of the new generated code:
```js
(() => {
function Cmp_HmrLoad(t) {
import(
/* @vite-ignore */ "/@ng/component?c=test.ts%40Cmp&t=" + encodeURIComponent(t)
).then((m) => m.default && i0.ɵɵreplaceMetadata(Cmp, m.default, [/* Dependencies go here */]));
}
(typeof ngDevMode === "undefined" || ngDevMode) && Cmp_HmrLoad(Date.now());
(typeof ngDevMode === "undefined" || ngDevMode) &&
import.meta.hot &&
import.meta.hot.on("angular:component-update", (d) => {
if (d.id === "test.ts%40Cmp") {
Cmp_HmrLoad(d.timestamp);
}
});
})();
```
PR Close#58465
named as the values of the `TaskType` type.
The Closure Compiler used at Google has a property renaming optimization
that can change the property names when minifying code. Having the
correct type helps the TSJS team that develops a tool to identfy
property renaming issues directly in TypeScript.
Signed-off-by: Costin Sin <sin.costinrobert@gmail.com>
PR Close#51739
The unused imports diagnostic reports once on the entire initializer and then again once per unused imports. This ends up being a bit hard to follow, because in a lot of cases the code snippet looks identical.
These changes switch to highlighting the `imports:` part of the property declaration and only highlighting the unused imports without a message.
PR Close#58468
This commit updates the code of the incremental hydration feature to make the `DeferBlockRegistry` class tree-shakable. The class is only needed for hydration cases and it should not be included into client bundles for client-only apps.
PR Close#58424