Fixes that the HMR dependency extraction logic wasn't handling some node types. Most of these are a bit edge-case-ey in component definitions, but variable initializers and arrow functions can realistically happen in factories.
PR Close#59445
in order for the docs to process function entry, this commit refactor function extraction by keeping the implementation as a the default entry and adds all the overloads into a separate array of entries.
fixes#56144
PR Close#56489
Fixes that the compiler wasn't capturing defer block dependencies correctly when `supportTestBed` is disabled. We had tests for this, but we didn't notice the issue because the dependencies ended up being captured because of the `setClassMetadata` calls. Once they're disabled, the dependencies stopped being recorded.
Fixes#59310.
PR Close#59313
During the HMR dependency analysis we need to check if an identifier is top-level or not. We do this by looking at each identifier and its parent, however we didn't account for some cases. These changes expand our logic to cover more of the common node types.
Related to https://github.com/angular/angular/issues/59310#issuecomment-2563963501.
PR Close#59323
Some time ago we narrowed down the expressions we support in two-way bindings, because in most cases any apart from property reads doesn't make sense. This ended up preventing users from using `$any` in the binding since it's considered a function call.
These changes update the validation logic to allow `$any`.
Fixes#51165.
PR Close#59362
We recently introduced a custom error to allow us to catch certain types
of errors. Unfortunately it doesn't work as expected in G3 because the
Node execution seems to run with ES5.
PR Close#59219
Fixes a null pointer error in the unused standalone imports diagnostic. It was caused by an inconsistency in TypeScript's built-in types.
Fixes#58872.
PR Close#59064
In the past two-way bindings used to be interpreted as `foo = $event` at the parser level. In #54065 it was changed to preserve the actual expression, because it was problematic for supporting two-way binding to signals. This unintentionally ended up causing the TCB to two-way bindings to look something like `someOutput.subscribe($event => expr);` which does nothing. It largely hasn't been a problem, because the input side of two-way bindings was still being checked, except for the case where the input side of the two-way binding has a wider type than the output side.
These changes re-add type checking for the output side by generating the following TCB instead:
```
someOutput.subscribe($event => {
var _t1 = unwrapSignalValue(this.someField);
_t1 = $event;
});
```
PR Close#59002
The `isSplitTwoWayBinding` function was a bit misleading, because it has side effects. Renames the function make it a bit more explicit.
PR Close#59002
The current HMR compiler assumes that there will only be one namespace import in the generated code (`@angular/core`). This is incorrect, because the compiler may need to generate additional imports in some cases (e.g. importing directives through a module). These changes adjust the compiler to capture all the namespaces in an array and pass them along.
Fixes#58915.
PR Close#58924
Currently host bindings are in a bit of a weird state, because their source spans all point to the root object literal, rather than the individual expression. This is tricky to handle at the moment, because the object is being passed around as a `Record<string, string>` since the compiler needs to support both JIT and non-JIT environments, and because the AOT compiler evaluates the entire literal rather than doing it expression-by-expression. As a result, when we report errors in one of the host bindings, we end up highlighting the entire expression which can be very noisy in an IDE.
These changes aim to report a more accurate error for the most common case where the `host` object is initialized to a `string -> string` object literal by matching the failing expression to one of the property initializers. Note that this isn't 100% reliable, because we can't map cases like `host: SOME_CONST`, but it's still better than the current setup.
PR Close#58870
This fixes an issue where the lazy-routes migration would crash for component classes a
decorator without arguments in front of the `@Component` decorator (in particular, it needed
to be the first decorator).
Fixes#58793
PR Close#58796
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
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
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
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
Previously, `filterMethodOverloads` excluded all members without a body, causing issues with the extraction of functions and members in TypeScript types.
PR Close#58445
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 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
Disables the standalone by default behavior in the compiler when running against and older version of Angular. This is necessary, because the language service may be using the latest version of the compiler against and older version of core in a particular workspace.
PR Close#58405
Reports a diagnostic if an NgModule refers to itself in its `imports` or `exports`. Previously the compiler would go into an infinite loop.
Fixes#58224.
PR Close#58231
Prior to this commit, each abstract method that was overloaded was extracted. With this commit it will be extracted only once. Every overload was and still will be supported by the signatures.
fixes#57693
PR Close#57707
Adds the ability to generate the function that replaces the component's metadata during HMR. The HMR update module is a function that is loaded dynamically and as such it has some special considerations:
* It isn't bundled, because doing so will result in multiple version of core.
* Since it isn't bundled, all dependencies have to be passed in as parameters. These changes include some special logic to determine and output those dependencies.
* While HMR is enabled, we have to disable the functionality that generates dynamic imports and drop the dependencies inside `@defer` blocks, because we need to retain the ability to refer to them in case they're needed inside the HMR update function.
* The function is returned by the `NgCompiler` as a string for the CLI's sake.
PR Close#58205
Currently only the prefix of namespace imports is configurable, but for HMR we need to know ahead of time what the name of `@angular/core` will be. These changes allow us to rewrite it.
PR Close#58205
While effective, `preservePlaceholders` unfortunately is not viable in google3 at the moment due to some complexities with how TC extracts messages. Therefore this feature is being removed in favor of whitespace trimming of expressions, which is viable for TC and provides most of the same benefit.
This is a partial revert of dab722f9c8.
PR Close#58176
With this commit directives, components & pipes are standalone by default.
To be declared in an `NgModule`, those require now `standalone: false`.
PR Close#58169
This commit is part of the migration to standalone by default and sets up 2 files with a default value for standalone. They are still `false` in this case to land the change into G3 first. The switch to `true` will be executed in a follow-up PR.
PR Close#58175
For the HMR initializer block to support being used in a Vite setup with
import analysis, the import call expression needs to be a runtime generated
value and include the `@vite-ignore` special comment. Without the first,
Vite will error prior to loading the application. Without the second, a
warning will be shown for each import which is effectively each component
within the application when HMR is enabled.
PR Close#58173
The compiler's AST factories now support generating a dynamic import call
expression with either a string literal or an expression. The later is useful
for cases where the URL is dynamically created at runtime. Also, a leading
comment can now be added to the URL for cases where bundler behavior
needs to be included via special comments.
PR Close#58173
We're using `path.relative` to compute a relative path between a `SourceFile` and the one of the `rootDirs`. The problem is that the `rootDirs` get passed through `getCanonicalFileName` which lowercases the path in some platforms, while `SourceFile.fileName` is always case-insensitive. This yields a path outside of the project which we were ignoring.
This change passes the `SourceFile.fileName` before passing it through `path.relative` to ensure that we get a valid result.
PR Close#58150
Consider a template with a context variable `a`:
```
<ng-template let-a>{{this.a}}</ng-template>
```
t push -fAn interpolation inside that template to `this.a` should intuitively read the class variable `a`. However, today, it refers to the context variable `a`, both in the TCB and the generated code.
In this commit, the above interpolation now refers to the class field `a`.
BREAKING CHANGE: `this.foo` property reads no longer refer to template context variables. If you intended to read the template variable, do not use `this.`.
Fixes#55115
PR Close#55183
Whenever information is requested from the template checker right now,
the shim is only ensured to be generated for the single file/component.
This is slow in migrations where we don't want to collect diagnostics,
but rather request information from the component state.
This commit supports `OptimizeFor` in `checker#getTemplate`.
PR Close#58106
Currently we don't defer any symbols that have references outside of the `import` statement and the `imports` array. This is a bit too aggressive, because it's possible that the symbol is only used for types (e.g. `viewChild<SomeCmp>('ref')`) which will be stripped when emitting to JS.
These changes expand the logic so that references inside type nodes aren't considered.
**Note:** one special case is when the symbol used in constructor-based DI (e.g. `constructor(someCmp: SomeCmp)`, because these constructors will be compiled to `directiveInject` calls. We don't need to worry about them, because the compiler introduces an addition `import * as i1 from './some-cmp';` import that it uses to refer to the symbol.
Fixes#55991.
PR Close#58104
To provide support for HMR of inline component styles (`styles` decorator field), the AOT
compiler will now use the resource host transformation API with the Angular CLI to provide
external runtime stylesheet URLs when the `externalRuntimeStyles` compiler option is enabled.
This allows both a component's file-based and inline styles to be available for HMR when used
with a compatible development server such as with the Angular CLI. No behavioral change is
present if the `externalRuntimeStyles` option is not enabled or the resource host transformation
API is not used.
An `order` numeric field is also added to the transformation API which allows consumers such as
the Angular CLI to create identifiers for each inline style in a specific containing file.
PR Close#57613
The AOT compiler now has the capability to handle component stylesheet files as
external runtime files. External runtime files are stylesheets that are not embedded
within the component code at build time. Instead a URL path is emitted within a component's
metadata. When combined with separate updates to the shared style host and DOM renderer,
this will allow these stylesheet files to be fetched and processed by a development
server on-demand. This behavior is controlled by an internal compiler option `externalRuntimeStyles`.
The Angular CLI development server will also be updated to provide the serving functionality
once this capability is enabled. This capability enables upcoming features such as automatic
component style hot module replacement (HMR) and development server deferred stylesheet processing.
The current implementation does not affect the behavior of inline styles. Only the
behavior of stylesheet files referenced via component properties `styleUrl`/`styleUrls`
and relative template `link` elements are changed by enabling the internal option.
PR Close#57613