396 Commits

Author SHA1 Message Date
Kristiyan Kostadinov 7e61217170 fix(compiler-cli): consider pre-release versions when detecting feature support (#59061)
Fixes that the logic which checks whether a feature is supported didn't account for pre-releases.

Fixes https://github.com/angular/vscode-ng-language-service/issues/2123.

PR Close #59061
2024-12-05 16:15:12 -08:00
Kristiyan Kostadinov fb1fa8b0fc fix(compiler-cli): more accurate diagnostics for host binding parser errors (#58870)
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
2024-11-25 15:25:48 +00:00
Paul Gschwendtner d4d76ead80 fix(compiler-cli): do not fail fatal when references to non-existent module are discovered (#58515)
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
2024-11-06 13:04:22 +01:00
Kristiyan Kostadinov dbe612f2cd fix(compiler-cli): disable standalone by default on older versions of Angular (#58405)
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
2024-10-30 09:23:12 -07:00
Matthieu Riegler c79b62ced2 refactor(core): remove the standalone feature (#58288)
By removing the standalone feature, we reduce the amount of code generated for components but at the cost of including the `StandaloneService` in the main bundle even if no standalone components are included in it.

PR Close #58288
2024-10-24 16:19:02 -07:00
Matthieu Riegler d9ac59c88f refactor(compiler): update compliance tests. (#58238)
`standalone: true` is now the default at runtime.

PR Close #58238
2024-10-24 12:44:13 -07:00
Kristiyan Kostadinov d0c74f3891 fix(compiler-cli): report when NgModule imports or exports itself (#58231)
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
2024-10-18 09:26:44 +00:00
Kristiyan Kostadinov 231e6ff6ca feat(compiler-cli): generate the HMR replacement module (#58205)
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
2024-10-16 07:22:45 +00:00
Matthieu Riegler 7ed566524d refactor(compiler-cli): Migrate manually ngtsc tests to standalone by default (#58169)
This commit is part of the migration to standalone by default.

PR Close #58169
2024-10-15 16:05:14 +00:00
Charles Lyding bbca205d5e refactor(compiler): adjust HMR initializer block for improved Vite support (#58173)
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
2024-10-14 15:21:40 +00:00
Matthieu Riegler 7aa3097ab6 refactor(compiler-cli): Migrate manually ngtsc tests to standalone by default (#58160)
This commit is part of the migration to standalone by default.

PR Close #58160
2024-10-14 14:58:58 +00:00
Kristiyan Kostadinov fb44323c51 fix(compiler-cli): incorrectly generating relative file paths on case-insensitive platforms (#58150)
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
2024-10-11 07:03:15 +00:00
Kristiyan Kostadinov 852c042520 refactor(compiler-cli): output HMR initializer code (#58150)
Adds the logic to the compiler that will output the HMR initializer code for each component, if enabled.

PR Close #58150
2024-10-11 07:03:15 +00:00
Joey Perrott 9dbe6fc18b refactor: update license text to point to angular.dev (#57901)
Update license text to point to angular.dev instead of angular.io

PR Close #57901
2024-09-24 15:33:00 +02:00
Kristiyan Kostadinov d9d68e73d2 fix(compiler): reduce chance of conflicts between generated factory and local variables (#57181)
Currently we use some short variable names like `t` and `r` in the generated factory functions. They can conflict with local symbols with the same names, if they're used for DI.

These changes rename the parameters to reduce the change for conflicts.

Fixes #57168.

PR Close #57181
2024-08-07 17:25:05 +00:00
Jessica Janiuk d73a3741a2 Revert "fix(compiler): reduce chance of conflicts between generated factory and local variables (#57181)" (#57230)
This reverts commit 67e09404db.

PR Close #57230
2024-08-01 19:33:04 +00:00
Paul Gschwendtner e11c0c42d2 fix(compiler-cli): run JIT transforms on @NgModule classes with jit: true (#57212)
This commit is similar to 98ed5b609e, and
makes use of the preparation work implemented there.

Similar to directives and components marked via `jit: true`, we also
need to do the same for JIT marked `@NgModule` classes. This is mostly
important for downleveling of decorators to support dependency injection
of such classes.

Inside Google3, migrating from `ts_library` to `ng_module` turns of
decorator downleveling, so the `jit: true` for NgModule's is implicitly
requesting/reliant on this transform— as expected.

PR Close #57212
2024-07-31 14:14:14 +00:00
Kristiyan Kostadinov 67e09404db fix(compiler): reduce chance of conflicts between generated factory and local variables (#57181)
Currently we use some short variable names like `t` and `r` in the generated factory functions. They can conflict with local symbols with the same names, if they're used for DI.

These changes add a `ɵ` to the generated variables to reduce the chance of conflicts.

Fixes #57168.

PR Close #57181
2024-07-29 13:46:48 -07:00
Paul Gschwendtner 98ed5b609e feat(compiler-cli): run JIT transform on classes with jit: true opt-out (#56892)
Currently when compiling code with the Angular compiler, all classes
with Angular decorators are compiled with AOT. This includes type
checking, scope collection etc.

This may not be desirable for all components, e.g. dynamic components,
or test components w/ `TestBed.configureTestingModule` (if compiled with ngtsc).

Those components can opt out of AOT on a per component-basis via `jit:
true`. This is helpful as it allows incremental migrations/refactorings
to AOT. Whether we want to keep this capability long-term is something
to be discussed separately.

For now though, we should fix that components compiled with `jit: true`
actually work as expected. Currently this **not the case** as soon as
the new initializer APIs are used— as those do no longer declare class
metadata with decorators.

This commit runs the JIT transform on JIT-opted classes.

Related: https://docs.google.com/document/d/1ox4atCJldWWDXlaYgwM-hU8BNsTpKNW7gx8OfZ0HtRY/edit?resourcekey=0-G1haTNYtD-dN0vNRkQ8_OQ&tab=t.0

PR Close #56892
2024-07-10 17:29:19 +02:00
Kristiyan Kostadinov e5a6f91722 feat(core): support TypeScript 5.5 (#56096)
Updates the repo to add support for TypeScript 5.5. Includes resolving some compilation errors and broken tests.

PR Close #56096
2024-05-29 15:33:33 +02:00
Kristiyan Kostadinov aa8df1d029 refactor(core): clean up clang comments and workarounds (#55750)
Since we aren't using clang anymore, we can remove the comments and the workarounds that were in place to prevent it from doing the wrong thing.

PR Close #55750
2024-05-13 11:10:36 -07:00
Joey Perrott 0d78a92431 refactor: migrate compiler-cli to prettier formatting (#55485)
Migrate formatting to prettier for compiler-cli from clang-format

PR Close #55485
2024-04-29 10:25:43 -07:00
Kristiyan Kostadinov 4eb0165750 fix(compiler): remove support for unassignable expressions in two-way bindings (#55342)
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.

In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.

Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.

BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.

PR Close #55342
2024-04-16 17:26:09 +02:00
Kristiyan Kostadinov 39624c6b12 fix(compiler): output input flags as a literal (#55215)
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.

PR Close #55215
2024-04-04 11:13:52 -07:00
Andrea Canciani f3b624553a refactor: fix a number of typos throughout the codebase (#55018)
Fix some typos detected using spellchecking tools, both in
documentation and in code (comments, identifiers).

PR Close #55018
2024-03-27 10:54:31 -07:00
Paul Gschwendtner d01576b104 refactor(compiler-cli): properly preserve file overview comments (#54819)
This commit updates the logic for preserving file overview comments
to be more reliable and less dependent on previous transforms.

Previously, with the old import manager, we had a utility called
`addImport` that always separated import statements and non-import
statements. This meant that the non-emitted statement from Tsickle
for the synthetic file-overview comments no longer lived at the
beginning of the file.

`addImports` tried to overcome this by adding another new non-emitted
statement *before* all imports. This then was later used by the
transform (or was assumed!) to attach the synthetic file overview
comments if the original tsickle AST Node is no longer at the top.

This logic can be improved, because the import manager shouldn't need to
bother about this fileoverview non-emitted statement, and the logic for
re-attaching the fileoverview comment should be local. This commit fixes
this and makes it a local transform.

PR Close #54819
2024-03-15 15:09:41 -07:00
Paul Gschwendtner 2564b45b47 test: replace fake_core with real @angular/core output (#54650)
This commit replaces `fake_core` with the real `@angular/core`
output. See previous commit for reasons.

Overall, this commit:

* Replaces references of `fake_core`
* Fixes tests that were testing Angular compiler detection that _would_
  already be flagged by type-checking of TS directly. We keep these
  tests for now, and add `@ts-ignore` to verify the Angular checks, in
  case type checking is disabled in user applications- but it's worth
  considering to remove these tests. Follow-up question/non-priority.
* Adds `@ts-ignore` to the tests for `defer` 1P because the property is
  marked as `@internal` and now is (correctly) causing failures in the
  compiler test environment.
* Fixes a couple of tests with typos, wrong properties etc that
  previously weren't detected! A good sign.

PR Close #54650
2024-03-06 12:34:38 +01:00
Paul Gschwendtner 5afa4f0ec1 fix(compiler-cli): support ModuleWithProviders literal detection with typeof (#54650)
As part of improving test safety of the compiler, I've noticed that
we have a special pass for detecting external `ModuleWithProviders`
where we detect the module type from an object literal.

This literal is structured like the following: `{ngModule: T}`. The
detection currently takes `T` directly, but in practice it should be
`typeof T` to satisfy the `ModuleWithProviders` type that is accepted
as part of `Component#imports`.

This commit adds support for this, so that we can fix the unit test
in preparation for using the real Angular core types in ngtsc tests.

PR Close #54650
2024-03-06 12:34:38 +01:00
Dylan Hunn 1a6beae8a2 feat(compiler): Enable template pipeline by default. (#54571)
Template pipeline is now the default template compiler.

A pair of source map tests is failing, related to DI in JIT mode; I will fix and re-enable these during the preview period.

PR Close #54571
2024-02-23 11:15:36 -08:00
Kristiyan Kostadinov a9f563f043 refactor(compiler-cli): move defer block tests into separate file (#54499)
Splits the tests for `@defer` blocks out into a separate file since the `ngtsc_spec.ts` is getting quite large.

PR Close #54499
2024-02-21 15:22:36 -08:00
Kristiyan Kostadinov badda0c389 fix(compiler-cli): correctly detect deferred dependencies across scoped nodes (#54499)
This is based on an internal issue report.

An earlier change introduced a diagnostic to report cases where a symbol is in the `deferredImports` array, but is used eagerly. The check worked by looking through the deferred blocks in a scope, resolving the scope for each and checking if the element is within the scope. The problem is that resolving the scope won't work across scoped node boundaries. For example, if there's a control flow statement around the block or within the block but around the deferred dependency, it won't be able to resolve the scope since it isn't a direct child, e.g.

```
@if (true) {
  @defer {
   <deferred-dep/>
  }
}
```

To fix this the case where the deferred block is inside a scoped node, I've changed the `R3BoundTarget.deferBlocks` to be a `Map` holding both the deferred block and its corresponding scope. Then to resolve the case where the dependency is within a scoped node inside the deferred block, I've added a depth-first traversal through the scopes within the deferred block.

PR Close #54499
2024-02-21 15:22:36 -08:00
JoostK 0c8744c73e fix(compiler-cli): use correct symbol name for default imported symbols in defer blocks (#54495)
This commit addresses a problem with PR #53695 that introduced support for default imports,
where the actual dynamic import used in the defer loading function continued to use the
symbol name, instead of `.default` for the dynamic import. This issue went unnoticed in the
testcase because a proper instance was being generated for the `ɵsetClassMetadataAsync` function,
but not the generated dependency loader function.

Fixes #54491

PR Close #54495
2024-02-20 09:45:32 -08:00
Paul Gschwendtner bfbb30618b fix(compiler-cli): do not error due to multiple components named equally (#54273)
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
2024-02-06 17:33:23 +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
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
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
Kristiyan Kostadinov cbe6e1ffcf refactor(compiler): allow some invalid expressions in two-way bindings that previously worked by accident (#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
2024-02-01 14:39:32 +00: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
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
Andrew Kushnir 79fbc4eaba refactor(compiler-cli): add tests for defer blocks and local compilation (#53591)
This commit adds tests to cover local compilation support for `@defer` blocks.

PR Close #53591
2024-01-10 15:28:59 -08:00
Paul Gschwendtner e934f3a581 refactor(compiler-cli): add diagnostic for inputs declared on static members (#53808)
Currently when someone declares a signal or non-signal input on a static
class member, the compiler will not yield any diagnostic. We can detect
these mistakes and report a diagnostic to help our users.

PR Close #53808
2024-01-10 12:21:06 +00:00
Paul Gschwendtner cfab5a59d6 refactor(core): detect signal input transforms independently of flag (#53808)
This commit changes the `HasTransform` flag to be only concerned with
decorator inputs. This allows us to automatically detect signal input
transforms without reliance on the flag, resulting in less complexity in
the compiler (as outlined in the design doc) and various  other places,
while it also allows us to simplify JIT support for signal inputs
because there would be no need to capture the "hasTransform" state in
the decorator so that JIT can generate the according input flags.

`isSignal` will still persist as an input flag to allow for monomorphic
and highly efficient distinguishing at runtime, whether an input is
signal based or not. JIT transform will also need to propagate this
information to the runtime somehow.

PR Close #53808
2024-01-10 12:21:04 +00:00
Paul Gschwendtner 36318dbd41 refactor(compiler-cli): reference InputFlags enum directly for full compiler output (#53571)
Instead of computing the bit input flags at compile-time and inling
the final bit flag number, we will use the `InputFlags` enum directly.
This is a little more code in the compiler side, but will allow us to
have better debuggable development code, and also prevents problems
where runtime flag bitmasks differ from the compiler flag bitmasks.

This is in practice a noop for optimized applications as the enum values
would be inlined anyway. This matches existing compiler emit for e.g.
change detection strategy, or view encapsulation enums.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner 1d95a832e3 refactor(core): detect signal inputs at runtime using input flags (#53571)
This commit introduces a new enum for capturing additional metadata
about inputs. Called `InputFlags`. These will be built up at compile
time and then propagated into the runtime logic, in a way that does
not require additional lookup dictionaries data structures, or
additional memory allocations for "common inputs" that do not have any flags.

The flags will incorporate information on whether an input is signal
based. This can then be used to avoid megamorphic accesses when such
input is set- as we'd not need to check the input field value. This also
avoids cases where an input signal may be used as initial value for an
input (as we'd not incorrectly detect the input as a signal input then).

The new metadata emit will be useful for incorporating additional
metadata for inputs, such as whether they are required etc (although
required inputs are a build-time only construct right now- but this is a
good illustration of why input flags can be useful). An alternative
could have been to have an additional boolean entry for signal inputs,
but allocating a number with more flexible input flags seems more future
proof and more reasonable andreadable.

More information on the megamorphic access when updating an input
signal
https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit.

PR Close #53571
2024-01-04 12:07:13 -08:00
Kristiyan Kostadinov b98d8f79ed fix(compiler): handle ambient types in input transform function (#51474)
Fixes that the compiler was throwing an error if an ambient type is used inside of an input `transform` function. The problem was that the reference emitter was trying to write a reference to the ambient type's source file which isn't necessary.

Fixes #51424.

PR Close #51474
2023-12-13 09:15:17 -08:00
Kristiyan Kostadinov 49cbe43886 refactor(compiler): add flag to disable block syntax in language service (#52683)
Adds the private `_enableBlockSyntax` flag that can be used by the language service to disable blocks on apps that aren't on Angular v17.

PR Close #52683
2023-11-08 09:34:10 -08:00
JoostK 581eff4ab1 fix(compiler-cli): use originally used module specifier for transform functions (#52437)
Prior to this change, the transform function would be referenced with a potentially
relative import into an external declaration file. Such imports are not portable
and should not be created in this context. This commit addresses the issue by threading
though the originally used module specifier by means of the `Reference` type.

Fixes #52324

PR Close #52437
2023-10-31 13:42:50 -07:00
JoostK 0c7accf92d fix(compiler-cli): properly emit literal types in input coercion function arguments (#52437)
This commit fixes an issue where using literal types in the arguments of an input coercion
function could result in emitting invalid output, due to an assumption that TypeScript makes
when emitting literal types. Specifically, it takes the literal's text from its containing
source file, but this breaks when the literal type node has been transplanted into a
different source file. This issue has surfaced in the type-check code generator and is
already being addressed there, so this commit moves the relevant `TypeEmitter` class
from the `typecheck` module to the `translator` module, such that it can be reused for
emitting types in the type translator.

Fixes #51672

PR Close #52437
2023-10-31 13:42:50 -07:00
Kristiyan Kostadinov b6b5adca38 fix(compiler): account for type-only imports in defer blocks (#52343)
Fixes that `@defer` blocks didn't account for type-only imports which could cause the import to be considered as not deferrable.

PR Close #52343
2023-10-24 09:20:49 -07:00
Payam Valadkhan 1eefa0c9c4 refactor(compiler-cli): include forbidOrphanComponents option in component's debug info (#52061)
A new flag added to the component's debug info to determine whether to throw runtime error (in dev mode) if component is being rendered without its NgModule. This flag is only set for non-standalone components.

PR Close #52061
2023-10-10 15:30:26 -07:00