When the linker is running using an unpublished version of angular, locally built, the version will be `0.0.0`.
When encountering this situation, the range that for the linker map support is considered to be `*.*.*` allowing
for the linker to work at build time with packages built with versioned angular.
Most notably this allows for us to properly use the linker in building our documentation site with the locally
built version of angular.
PR Close#54439
The version detection condition for signal two-way bindings used an OR
instead of an AND, resulting in every `.0` patch version being considered
as supporting two-way bindings to signals.
This commit fixes the logic and adds additional parentheses to ensure the
meaning of the condition is more clear. Long term, we should switch to
semver version parsing instead.
PR Close#54443
In order to allow both signals and non-signals in two-way bindings, we have to pass the expression through `ɵunwrapWritableSignal`. The problem is that the language service uses a bundled compiler that is fairly new, but it may be compiling an older version of Angular that doesn't expose `ɵunwrapWritableSignal` (see https://github.com/angular/vscode-ng-language-service/issues/2001).
These changes add a `_angularCoreVersion` flag to the compiler which the language service can use to pass the parsed Angular version to the compiler which can then decide whether to emit the function.
PR Close#54423
Currently all triggers are set up to show the placeholder block on the server, except for `on immediate` which is basically a noop. These changes update `on immediate` to match the rest of the triggers.
Fixes#54385.
PR Close#54394
Getting the typing for `ɵunwrapWritableSignal` just right was tricky so these changes add some tests to ensure that we don't regress.
Also reworks the type tester a bit to make it easier to find where to add new test files.
PR Close#54387
This commit updates the implementation of the `customElements` patch and also
patches FACE callbacks (`formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`
and `formStateRestoreCallback`). This now allows invoking those callbacks in the same zone
where the custom element has been defined.
PR Close#50686
Assure that the same readonly array corresponding to the children query results
is returned for cases where a query is marked as dirty but there were no actual
changes to the content of the results array (this can happen if a view is added
and removed thus marking queries as dirty but not influencing final results).
Fixes#54376
PR Close#54392
The newly introduced signal queries would error if no match exists, due to an
invalid read within the query internals.
This commit addresses the crash by allowing there to be no matches.
PR Close#54353
Currently we have two fake copies of `@angular/core` in the compiler tests which can be out of sync and cause inconsistent tests. These changes reuse a single copy instead.
PR Close#54344
This updates some tests to use the public imports from `@angular/core` now that they are available,
and cleans up useless imports and inaccurate names.
PR Close#54334
In some situations, calling `markForCheck` can result in an infinite
loop in seemingly valid scenarios. When a transplanted view is inserted
before its declaration, it gets refreshed in the retry loop of
`detectChanges`. At this point, the `Dirty` flag has been cleared from
all parents. Calling `markForCheck` marks the insertion tree up to the
root `Dirty`. If the declaration is checked again as a result (i.e.
because it has default change detection) and is reachable because its
parent was marked `Dirty`, this can cause an infinite loop. The
declaration is refreshed again, so the insertion is marked for refresh
(again). We enter an infinite loop if the insertion tree always calls
`markForCheck` for some reason (i.e. `{{createReplayObservable() | async}}`).
While the case above does fall into an infinite loop, it also truly is a
problem in the application. While it's not an infinite synchronous loop,
the declaration and insertion are infinitely dirty and will be refreshed
on every change detection round.
Usually `markForCheck` does not have this problem because the `Dirty`
flag is not cleared until the very end of change detection. However, if
the view did not already have the `Dirty` flag set, it is never cleared
because we never entered view refresh. One solution to this problem
could be to clear the `Dirty` flag even after skipping view refresh but
traversing to children.
PR Close#54329
The `subscribe` methods on `ModelSignal` and `OutputEmitter` were marked as `@internal` which will break when the TCB needs to reference them. These changes make them `@deprecated` temporarily so we can address the properly later.
PR Close#54342
The new `model()` signal introduces a `ModelSignal` type that needs to be handled by the interpolatedSignalNotInvoked diagnostic to catch issues like:
```
<div>{{ myModel }}</div>
```
PR Close#54338
Add an image loader for Netlify Image CDN. It is slightly different in implementation from existing loaders, because it allows absolute URLs
Fixes#54303
PR Close#54311
The import of `module` can conflict with the native global variable called `module` and can break some internal tests. These switch to only importing the function we need.
PR Close#54333
This helps with the Angular CLI currently swallowing fatal diagnostic
errors in ways that are extremely difficult to debug due to workers
executing Angular compiler logic.
The worker logic, via piscina, is currently not forwarding such Angular
errors because those don't extend `Error.`
a7042ea27d/src/worker.ts (L175)
Even with access to these errors by manually forwarding errors, via
patching of the Angular CLI, there is no stack trace due to us not using
`Error` as base class for fatal diagnostic errors. This commit improves
this for future debugging and also better reporting of such errors to
our users- if we would accidentally leak one.
PR Close#54309
An identical addition to: 760b1f3d0b.
This commit expands the `try/catch`-es:
- to properly NOT throw and just convert the diagnostic.
- to be in place for all top-level instances. Notably, this logic cannot
reside in the template type checker directly as otherwise we would
risk multiple duplicate diagnostics.
PR Close#54309
Fixes that `ɵunwrapWritableSignal` inferring getter functions as not matching the interface of `WritableSignal` instead of preserving them.
PR Close#54252
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.
PR Close#54252
Reworks the TCB for two-way bindings to make them simpler and to avoid regressions for two-way bindings to generic inputs. The new TCB looks as follows:
```
var _t1: Dir;
var _t2 = _t1.input;
(_t1 as typeof _t2 | WritableSignal<typeof _t2>) = expression;
```
PR Close#54252
Adds support for model inputs in the framework. `model()` returns a writable signal that implicitly defines a input/output pair that can be used either in two-way bindings to keep two values in sync or by binding individually to the input and output. When the value of the `model` changes, it will emit an event with the current value.
Furthermore, these changes expand two-way bindings to accept `WritableSignal`. This will make it easier to transition existing code to signals in a backwards-compatible way.
Example:
```ts
@Directive({
selector: 'counter',
standalone: true,
host: {
'(click)': 'increment()',
}
})
export class Counter {
value = model(0);
increment(): void {
this.value.update(current => current + 1);
}
}
@Component({
template: `<counter [(value)]="count"/> The current count is: {{count()}}`,
})
class App {
count = signal(0);
}
```
PR Close#54252
This commit improves IDE completion of the `read` option for
signal-based queries.
Currently, TS only matches the first overload when starting out with
defining a query. TS doesn't build up the combination of possible
options from the second overload- so in practice users will only see
IDE completions for the `descendants` option.
This is not a problem for view queries as the only option is `read`, so
TS will always match the overload with the `read` option.
```
class X {
query = contentChild('', {^^ <--
here we should completion for `read` an `descendants`
}
```
PR Close#54280
Currently the error is a generic error "exportAs must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the error is a generic error "selector must be a string ...". This commit makes the error more specific to local compilation and adds some action items.
PR Close#54230
Currently the correct error message is shown only if @Component.styles is an array with some unresolved element. This change supports the new case of string type for the @Component.styles field.
PR Close#54230
A helper `validateLocalCompilationUnresolvedConst` is added to encapsulate a common pattern which leads to the error `LOCAL_COMPILATION_UNRESOLVED_CONST`.
PR Close#54230
The trailing error message comes from tracing the chain of DymaicValue which leads to a mostly useless error that highlights the same symbol as the original message and emits the error message "Unknown reference". This error message is removed in the favour of the original message which suffices.
PR Close#54230
A single error code is created to unify the common error pattern in local compilation mode where an imported const cannot be resolved, but needs to be resolved. This mainly happens for Angular decorator fields such as @Component.template.
The error messages are also upgraded to be more centered around this unifying theme.
PR Close#54230
Currently, when two components are named `TestComponent`, and both would
use e.g. control flow. Templates would be generated by the compiler and
those would conflict at runtime because the names for the template
functions are not ensured to be unique.
This seems like a more general problem that could be tackled in the
future in the template pipeline by always using the `ConstantPool`, but
for now, we should be good already, given us ensuring the `baseName`'s are
always unique.
PR Close#54273
This commit updates the implementation of the zone.js `fs` patch to
restore the implementation of `realpath.native` and patches it as a macrotask,
along with other functions of the `fs` package. This is the only nested function
that must be patched.
Closes: #45546
PR Close#54208
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
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
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
The compileNgModuleFactory dont need to be in the application_ref file (in fact
the whole logic has little to do with ApplicationRef and it is not even called
from the application_ref). Performing this move to avoid circular dependencies
when the new query as signals authoring functions are exported.
PR Close#54103
This commit changes the approach to the reactive node representing query
results: instead of creating a custom node type we can use a computed -
the main change to get there is representing dirty change notification as
a signal (a counter updated every time a query changes its dirty status).
This change is dictated by simplification (we can avoid creation of a custom
signal type) as well as fixes to the multiple issues not covered by the
initial implementation:
- assuring referential stability of results (ex.: the same array instance
returned from child queries until results change);
- per-view results collection to avoid a situation where accessing query
results during view creation would return partial / inconsistent results;
- proper refresh of query results for both live and non-connected consumers.
All the above cases are covered by the additional tests in this commit.
PR Close#54103
This commit adds tests for content queries and fixes the arguments
order in the contentQuerySignal instruction, thus fixing a bug
discovered while adding tests.
PR Close#54103
This commits converts the hand-written tests into their usual,
compiled form. We can perform this change now since the compiler
bits of the queries-as-signal story landed.
PR Close#54103
This commit updates the logic of defer blocks to create an internal pending task to indicate that an application is not yet stable. This change would be helpful for zoneless applications.
PR Close#54239
Updates the acceptance authoring test compiler targets to support
multiple spec files. This will be useful for output, model, inputs
and queries.
PR Close#54253
The `listener` instruction currently always assumes RxJS subscribables,
and verifies this via `isSubscribable`. The type narrowing is not
ignored and the type remains `any` given the `ngDevMode` check.
This commit improves type safety, and actually switches to a dedicated
interface for "output subscribable" values. This is needed because
`Subscribable` from `RxJS` is typed to expect an observer in object
literal form- which is not correct and doesn't apply to `EventEmitter`
and matches the form of `.subscribe` we are using in the `listener`
instruction.
PR Close#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
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
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
Adds an ngtsc diagnostic and compilation output test for `output()`. The
test will verify certain recognition restrictions and ensures that
diagnostics are raised, in addition to proper full compilation output
being generated (aside from the compliance tests verifying output more
closely).
PR Close#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
This commit introduces the `output()` function and corresponding
runtime code.
In practice, `output()` will defer to `EventEmitter` as outlined in the
RFC, but we are considering limiting the type to a minimal version that
is not coupled with RxJS, less complex, and also has better type safety
around emitting of values.
E.g. currently `EventEmitter.emit` can always be called without
any value, even though the output may be typed to always pass around
values of type `T`. This could cause subtle and confusing bugs.
PR Close#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
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
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
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
Consider the following very quirky Angular template, which has both an i18n attribute binding and a property binding to `in`:
```
<cmp [in]="foo" in="bar" i18n-in />
```
What would you expect the above template to do? `TemplateDefinitionBuilder` will emit the following Ivy instructions:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
}
}
```
This makes some sense -- we create a single element, and attach an i18n message to the `in` attribute. But is this actually correct? Notice that the property binding is completely missing!
Indeed, Template Pipeline actually produces this code:
```
// Element constant attributes
consts: () => {
__i18nMsg__('bar', [], {}, {})
return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
// Create mode
i0.ɵɵelement(0, "cmp", 0);
} else if (rf & 2) {
// Update mode
i0.ɵɵproperty("in", ctx.foo);
}
}
```
Aha! There's the property binding! Arguably, this is a bug in `TemplateDefinitionBuilder`, but after some discussion on Slack, we have decided to ban this practice in a future Angular version.
For now, we allow Template Pipeline to have slightly different output, but print an error to warn the user of the issue.
PR Close#54063
This test ensures that the `ExpressionChanged...` error does not happen
when signals are updated in a view that is attached to `ApplicationRef`
but was already checked. This was fixed in 432afd1ef4
which actually consequently fixes it for regular `markForCheck` as well.
PR Close#54206
* Renames the `input_signals` directory to `signals` so it can be reused for other tests.
* Reworks the build file to allow multiple test files.
PR Close#54213
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
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
One of the earlier commits separated one-way and two-way bindings which ended up breaking some internal targets, because it changed the assignment order. These changes bring back the old order.
PR Close#54154
In one of the earlier commits, the logic that appends `=$event` before parsing two-way bindings was removed and some validation was added to prevent unassignable expressions from being used. This ended up being problematic, because previously the parser was incorrectly allowing some invalid expressions which users came to depend on. For example, it transformed `[(value)]="a && a.b"` to `a && (a.b = $event)`.
These changes add some special cases for the common breakages that came up during the TGP.
PR Close#54154
Updates the template definition builder to emit the new format for the listener side of two-way bindings.
```js
// Before
listener("ngModelChange", function($event) {
return ctx.name = $event;
});
// After
ɵɵtwoWayListener("ngModelChange", function($event) {
ɵɵtwoWayBindingSet(ctx.name, $event) || (ctx.name = $event);
return $event;
});
```
PR Close#54154
Currently the listener side two-way listeners are parsed by appending `=$event` to the raw expression. This is problematic, because:
1. It can interfere with other expressions (see #37809).
2. It can lead to confusing error messages because users will see code that they didn't write.
3. It doesn't allow us to further manipulate the expression.
These changes remove the logic that appends `=$event` to resolve the issue. There's also some new logic that checks the expression after it has been parsed to ensure that the result is an assignable expression.
Subsequent commits will update the code that emits the expression to add back the `$event` assignment where it's needed.
PR Close#54154
Adds the following new instructions:
* `twoWayBindingSet` - used to assign values inside of the listener side of a two-way binding. Currently a noop, but will come into play later.
* `twoWayListener` - used to bind a two-way listener. Currently calls directly into `listener`, but it may be useful in the future.
PR Close#54154
Currently all the members of `_ParseAST` are public, even though they're all used only within the class. This change marks them as private so that it's explicit which ones are intended to be used outside the class.
PR Close#54154
Reworks the compiler so that it generates a `twoWayProperty` instruction, instead of `property`, for the property side of a two-way binding. Currently the new instruction passes through to `property`, but it'll have some two-way-binding-specific logic in subsequent PRs.
PR Close#54154
It was always the intent to have `afterRender` hooks allow updating
state, as long as those state updates specifically mark views for
(re)check. This commit delivers that behavior. Developers can now use
`afterRender` hooks to perform further updates within the same change
detection cycle rather than needing to defer this work to another round
(i.e. `queueMicrotask(() => <<updateState>>)`). This is an important
change to support migrating from the `queueMicrotask`-style deferred
updates, which are not entirely compatible with zoneless or event `NgZone` run
coalescing.
When using a microtask to update state after a render, it
doesn't work with coalescing because the render may not have happened
yet (coalescing and zoneless use `requestAnimationFrame` while the
default for `NgZone` is effectively a microtask-based change detection
scheduler). Second, when using a `microtask` _during_ change detection to defer
updates to the next cycle, this can cause updates to be split across
multiple frames with run coalescing and with zoneless (again, because of
`requestAnimationFrame`/`macrotask` change detection scheduling).
PR Close#54074
This change updates the `checkNoChanges` pass to only run once after
both view refresh and `afterRender` hooks execute rather than both
before and after the hooks. The original motivation was to specifically
ensure that the application was in a "clean state" before running the
`afterRender` hooks and ensure that `afterRender` hooks don't "fix"
`ExpressionChanged...` errors. This, however, adds to the complexity and
cost of running change detection in dev mode. Instead, the
`checkNoChanges` pass runs once we have done all render-related work and
want to ensure that the application state has been synced to the DOM
(without additional changes).
PR Close#54074
Errors during change detection are terminal and we do not generally
attempt to continue processing or recover after one occurs. This helps clean
up the `tick` implementation with respect to running `afterRender` hooks.
PR Close#54074
ISO 8601 defines
* Monday as the first day of the week.
* week 01 is the week with the first Thursday
Therefore:
Sunday Dec 31st 2023 is the last day of the last week of the year : W52 2023.
PR Close#53879
This commit updates the implementation of the `fetch` patch and additionally
patches `Response` methods which return promises. These are `arrayBuffer`, `blob`,
`formData`, `json` and `text`. This fixes the issue when zone becomes stable too early
before all of the `fetch` tasks complete. Given the following code:
```ts
appRef.isStable.subscribe(console.log);
fetch(...).then(response => response.json()).then(console.log);
```
The `isStable` observer would log `false, true, false, true`. This was happening because
`json()` was returning a native promise (and not a `ZoneAwarePromise`). But calling `then`
on the native promise returns a `ZoneAwarePromise` which notifies Angular about the task
being scheduled and forces to re-calculate the `isStable` state.
Issue: #50327
PR Close#50653
This commit updates the signature of the `ZoneGlobalConfigurations` interface and adds
missing `__Zone_ignore_on_properties` property, which may be setup to ignore specific `on`
properties from being patched.
PR Close#50737
`isNavigationCancelingError` & `isRedirectingNavigationCancelingError` had duplicate implementations. This commit also cleans-up those functions.
PR Close#53762
The `RadioControlRegistry` was only provided in a module, providedIn: 'root' fixes that issue.
Fixes#54117
Co-authored-by: sr5434 <118690585+sr5434@users.noreply.github.com>
PR Close#54130
This commit adds hydration informations to the devtools.
* List of hydrated/hydrated components
* Shows hydration overlays
* Shows hydration errors for NG0500, 501 & 502
PR Close#53910
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
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
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
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
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
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
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
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
This commit updates the router integration tests to cover both the
classic History and the new Navigation API. There is more work to be
done here, but this commit works to prove the efficacy of the
`FakeNavigation` implementation.
PR Close#53799
When the zoneless scheduler is provided, we want to update the behavior
of `ComponentFixture` to address common issues and painpoints in testing.
Developers should never have to call `detectChanges` on a fixture
manually. Instead of calling `detectChanges` after performing an
action that updates state and requies a template refresh, developers
should wait for change detection to run because the update needs to also have
notified the scheduler. If this was not the case, the component would
not work correctly in the application. Calling `detectChanges` to force
an update could hide real bugs.
This commit also updates the zoneless tests to uses `ComponentFixture`
instead of manually attaching to the `ApplicationRef` and rewriting a
lot of the helpers (`getDebugNode`, `isStable` as a value, `whenStable` as a
Promise).
PR Close#54024
Adds some logic to skip over `TestBed.configureTestingModule` calls where the `declarations` aren't initialized to an array. We can't migrate these cases, because test migrations don't have access to the Angular compiler. Previously the migration would throw a runtime error.
PR Close#54122
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