Commit graph

3851 commits

Author SHA1 Message Date
Kristiyan Kostadinov
57432f1b6a refactor(compiler-cli): merge duplicate directive matches and report conflicts
Implements the logic at the compiler level that will de-duplicate host directives and merge them together. It will also report if a conflict is detected during merging.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
22f9ee1be6 refactor(compiler): require a reference in DirectiveMeta
Requires the `DirectiveMeta` to have a `ref` so that we can find duplicates easily.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
d15ceff617 refactor(compiler-cli): move ClassPropertyMapping into compiler
Moves the `ClassPropertyMapping` into the compiler, rather than having to pass around the limited `InputOutputPropertySet` interface that is only implemented by `ClassPropertyMapping`.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
927ae3abc8 refactor(compiler): move matchSource into base metadata
Moves the `matchSource` into the base metadata so the binder can use it.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
4651b93a92 refactor(compiler-cli): pre-compute key
Updates the TCB metadata to pre-compute and store the `TcbReferenceKey`, instead of computing it on the fly.
2026-04-03 09:44:39 -07:00
Kristiyan Kostadinov
8fe025f514 feat(core): drop support for TypeScript 5.9
Drops support for TypeScript 5.9.

BREAKING CHANGE:
* TypeScript versions older than 6.0 are no longer supported.
2026-04-03 09:44:11 -07:00
SkyZeroZx
7f9450219f feat(compiler-cli): Adds warning for prefetch without main defer trigger
Emit a warning when an `@defer` block uses `prefetch` triggers but does not define an explicit main trigger.

Closes #52746
2026-04-02 12:21:09 -07:00
SkyZeroZx
b19fda0b15 refactor(compiler-cli): Add diagnostics for idle prefetch triggers
Extends the extended diagnostic for `@defer` trigger misconfiguration to include `on idle` triggers
2026-04-02 12:21:09 -07:00
Andrew Scott
75ac120493 fix(language-service): get quick info at local var location to align with TS semantics and support type narrowing
Previously, the Language Service fetched Quick Info and definitions for template variables (such as `@let` declarations) using mapping to their `initializerLocation` (the right-hand side expression). This aggressively bubbled the type, JSDoc, and definition identity of the initializer backwards onto the variable itself.

This approach had two flaws:
1. It broke type narrowing because the LS read the original un-narrowed type from the source expression rather than the type of the narrowed intermediate variable in the Type Check Block.
2. It deviated from native TypeScript semantics, where a local `let` binding (`let address = hero.address`) does not inherit the docstrings or `(property)` kind of its initializer, acting solely as a local inferred variable.

By using `localVarLocation` rather than `initializerLocation` for LetDeclaration Quick Info and Type Definitions, these intermediate variables now properly preserve type narrowing within templates and flawlessly match the standard behavior expected of TypeScript block variables. `VariableSymbol.initializerLocation` is retained solely to map the value spans of structural directive contexts (e.g., `exportAs` strings).

fixes #65491
2026-04-01 12:22:07 -07:00
Andrei Chmelev
fcd0bb0db8 fix(compiler-cli): prevent recursive scope checks for invalid NgModule imports
Avoid recursive local scope lookups when invalid NgModule imports create import cycles.
2026-03-27 16:10:01 +01:00
Kristiyan Kostadinov
d1c1bc3200 refactor(compiler-cli): decouple schema checker from typescript
Makes the `DomSchemaChecker` from TypeScript APIs.
2026-03-27 15:58:12 +01:00
Andrew Scott
c1261b02db refactor: extract comments utilities to private
allows comments utils to be used in other language service packages
2026-03-27 15:36:37 +01:00
Kristiyan Kostadinov
3382e8a34b refactor(compiler-cli): generalize out of band diagnostics recorder
Currently the `OutOfBandDiagnosticRecorder` is tied to producing TypeScript diagnostics, however some of our use cases might call for a different form.

These changes decouple the recorder from TypeScript and make the diagnostic type generic.
2026-03-25 12:59:11 -07:00
Kristiyan Kostadinov
9ee4f83705 build: update to TypeScript 6 stable
Updates the repo to the stable version of TypeScript 6.
2026-03-25 12:57:49 -07:00
Matthieu Riegler
eae8f7e30b feat(core): Set default Component changeDetection strategy to OnPush
The default change detection strategy is now OnPush.

BREAKING CHANGE: Component with undefined `changeDetection` property are now `OnPush` by default. Specify `changeDetection: ChangeDetectionStrategy.Eager` to keep the previous behavior.
2026-03-24 16:25:02 -07:00
Matthieu Riegler
8bc31a515f feat(core): Allow other expression for exhaustive typechecking
When the switched expression is nested within a union, exhaustive typechecking needs to know which expression to check.
This change adds the possibility of specifying the expression to check:

```
@Component({
  selector: 'app-root',
  imports: [],
  template: `
    @switch (state.mode) {
      @case ('show') { {{ state.menu }}; }
      @case ('hide') {}
      @default never(state);
    }
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
  state!: { mode: 'hide' } | { mode: 'show'; menu: number };;
}
```

fixes #67406
2026-03-24 14:42:28 -07:00
Matthieu Riegler
f46e8bd440 refactor(compiler): remove fullTemplateTypeCheck compiler option.
The option was deprecated back in v13. Users should use `strictTemplates: true`.
2026-03-23 11:33:15 -07:00
Kristiyan Kostadinov
63ac1bd2fd refactor(compiler-cli): decouple host element creation logic from TypeScript
Reworks the logic for constructing a `HostElement` node so that we can reuse it without depending on TypeScript APIs.
2026-03-23 11:16:39 -07:00
SkyZeroZx
ca67828ee2 refactor(compiler-cli): introduce NG8023 compile-time diagnostic for duplicate selectors
Add NG8023 extended diagnostic to report duplicate component selectors
during compilation.

This replaces the former NG0300 runtime error, ensuring the failure
occurs at build time instead of runtime.

Closes  angular#48377

BREAKING CHANGE: Elements with multiple matching selectors will now throw at compile time.
2026-03-19 16:12:02 -07:00
Alex Rickabaugh
41b1410cb8 feat(forms): support binding number|null to <input type="text">
`<input type="number">` often does not provide the desired user experience when editing numbers in
a form. MDN even [describes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/number#using_number_inputs)
how text inputs should be used in many cases instead, via `<input type="text" inputmode="numeric">`
or similar configurations. Previously, this did not work with Signal Forms without a custom input
component/directive.

This PR builds support for binding `number|null` models directly to `<input type="text">` native
controls via `[formField]`. When a model has a number or `null` value, signal forms will preserve
that status when the user makes edits/changes. Empty string values are converted to `null`, other
values are parsed as numbers, and a parse error is raised when a non-numeric value is entered.

Note that it's up to the UI developer to configure additional UI affordances such as setting an
appropriate `inputmode`, rejecting non-numeric keypresses, etc.

Fixes #66903
Fixes #66157
2026-03-19 15:26:34 -07:00
Kristiyan Kostadinov
c457b9b5b4 refactor(compiler): add ts-ignore comment on factory functions
Adds a `ts-ignore` comment to thew instantiation expressions in factories, because in some compilation modes we can't guarantee that they'll compile.
2026-03-18 14:05:18 -06:00
Kristiyan Kostadinov
9769560da7 fix(compiler-cli): generic types not filled out correctly in type check block
Fixes a regression caused by the recent TCB changes where we moved the type parameter processing earlier in the pipeline and stopped properly accounting for the `TcbGenericContextBehavior`.

Fixes #67704.
2026-03-17 13:21:27 -06:00
Alex Rickabaugh
c4ce3f345f feat(forms): template & reactive support for FVC
Implement support for `FormUiComponent`s in both Reactive and Template-driven
forms. This allows components that use the new signal-based form control
architecture to be used seamlessly within existing Angular form paradigms.

Key changes:
- Integrated `ɵngControlCreate` and `ɵngControlUpdate` lifecycle hooks into
  `NgModel`, `FormControlDirective`, and `FormControlName`.
- Implemented branching logic to choose between the traditional `ControlValueAccessor` (CVA) path and the new FVC path based on the host element's capabilities.
- Added comprehensive unit tests for FVC integration in both Reactive (`reactive_fvc.spec.ts`) and Template-driven (`template_fvc.spec.ts`) forms, covering:
    - Value synchronization (model -> view and view -> model).
    - Status synchronization (touched, dirty, valid, invalid, pending, required).
    - Error propagation and `parseErrors` support.
    - Fallback behavior to native DOM properties (disabled, required) when FVC inputs are missing.
    - Graceful fallback to CVA when no FVC pattern is detected.
- Refined `NgModel` to correctly handle `required` validation via its existing `RequiredValidator` directive while supporting FVC for other properties.
2026-03-17 13:18:26 -06:00
Andrew Scott
470cf430ce test(language-service): optimize language service test environment and flatten test setup
Optimization Goals:
The primary goals of this optimization are to dramatically reduce the execution time of the language-service test suite and stabilize the mock file system infrastructure. Previously, the suite suffered from significant overhead due to recreating the `MockFileSystem`, `MockServerHost`, and TypeScript `ProjectService` for every single test block, leading to redundant parsing operations, slow test initialization, and reduced spec performance.

How the Goals Were Achieved:
1. **Mock File System Optimizations (Shared State)**:
   - Evaluated that standard test files (e.g., TS/Angular lib definitions) are immutable across tests.
   - Introduced and utilized `lockMockFileSystem()` to initialize the mock `FileSystem` with `loadStandardTestFiles()` only once per test suite run rather than repeatedly per test.
   - Refactored `LanguageServiceTestEnv.setup()` to reuse the singleton file system, completely skipping redundant module loading by eagerly flagging `fsInitialized = true`.

2. **Language Service Test Environment Enhancements (TypeScript Project Reuse)**:
   - Implemented partial configuration reloads in the `Project` class via the `update()` method, removing the need to tear down and rebuild the entire `MockServerHost` and TypeScript `ProjectService` from scratch when minimal file changes (like HTML templates or local TS edits) are made dynamically by a test.
   - Applied `projectService.reloadProjects()` and `scriptInfo.reloadFromFile()` to synchronously push mock file tree invalidations to the active TS program, skipping expensive environment initialization and saving considerable latency across tests.
   - Added `projectName` identifiers inside complex isolate tests (e.g. module alias aliasing) so custom environment injections can sandbox safely without invalidating the global default environment cache.

3. **Test Suite Unification**:
   - Flattened fragmented test groups (`grp1`, `grp3`, `grp4`) into a cohesive single directory at `packages/language-service/test/`. This simplifies execution config, improves test runner concurrency, and unifies local development targeting.
   - Cleaned out broken inline debug logging and unneeded config reloading loops.

4. **Maintaining Test Isolation**:
   - **Explicit TypeScript Configuration**: While the underlying `MockFileSystem` ("disk") is aggressively reused across tests, the TypeScript `ProjectService` and its execution environment are entirely recreated for every test run to ensure isolated ASTs and module resolution caches.
   - **Strict tsconfig.json Files Array**: When a project is initialized, it explicitly defines its boundary using the strict `files: [ ... ]` array in `tsconfig.json`. This ensures that any leftover files physically on the mock disk from an older test run are completely invisible to the TS Compiler.
   - **Namespace Sandboxing**: For tests doing custom modifications (e.g., overriding module resolution paths), they utilize localized `projectName` arguments (like `"test_alias_completions"`) to configure sandboxed working directories.
2026-03-16 14:49:34 -06:00
Kristiyan Kostadinov
2bd708fb6b fix(compiler-cli): escape template literal in TCB
Fixes a regression introduced by #67381 where we weren't escaping backticks in template literals.

Fixes #67675.
2026-03-16 10:47:25 -06:00
Kristiyan Kostadinov
cd656701b0 refactor(compiler): update tests after codegen changes
Updates the compliance tests to account for the recent changes.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
cf3348a9ec refactor(compiler): rename isolated tests to codegen
Renames the test target so it's a bit clearer what it's targeting.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
4636218395 refactor(compiler-cli): avoid typescript errors from debugName transform
In some cases the `debugName` transform generates a spread into the signal function parameters. This can cause compiler errors, because the functions don't have rest parameters.

These changes work around it by adding a `@ts-ignore` above it.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
419944b800 refactor(compiler-cli): check if generated code compiles in compliance tests
Updates the compliance tests to check if the generated code compiles.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
4b80227efa refactor(compiler): allow leading comments on expressions
Updates the output AST to allow leading comments to be attached to expression nodes.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
7a0d6b8df2 fix(compiler-cli): transform dropping exclamationToken from properties
Fixes that the Ivy transform was dropping the `exclamationToken` from properties.
2026-03-16 09:58:18 -06:00
Kristiyan Kostadinov
412788fac9 fix(compiler): ensure generated code compiles
Initial pass to make sure some common cases produce code that compiles.
2026-03-13 11:13:03 -06:00
Kristiyan Kostadinov
ed9750d6d7 refactor(compiler-cli): update ast factories to account for type nodes
Updates the Babel and TypeScript AST factories to account to produce type nodes.
2026-03-13 11:13:03 -06:00
Kristiyan Kostadinov
1639fc565b refactor(compiler-cli): add type nodes to translator
Updates the translator and AST factories to account for type nodes.
2026-03-13 11:13:03 -06:00
Kristiyan Kostadinov
2831ff2330 refactor(compiler-cli): add generic for type nodes to AST factories
Updates the type factories and various usage sites to add a generic for type nodes.
2026-03-13 11:13:03 -06:00
SkyZeroZx
8edcf41760 refactor(compiler-cli): add warning for matching viewport @defer trigger options
Ensures that viewport `@defer` trigger prefetch warnings occur when the viewport options are identical, including cases with empty or no parameters.
2026-03-12 16:21:02 -06:00
Alan Agius
4febb8ad31 build: update aspect_rules_js to 3.0.2 (#67518)
This updates the major version of `aspect_rules_js`.

PR Close #67518
2026-03-11 13:37:33 -07:00
SkyZeroZx
66e72efef4 refactor(compiler-cli): simplifies IncrementalCompilation.fresh
Removes the `ts.Program` argument from the `IncrementalCompilation.fresh` method.
2026-03-11 09:41:02 -07:00
Ibrahim Hussien
903d51e855 docs: combine multiple documentation improvements into one PR 2026-03-11 09:29:45 -07:00
Andrew Scott
dbbc38ad14 refactor(compiler-cli): Export hybrid analysis from bin
This is necessary to actually use the exported symbols. Verified by building locally
2026-03-10 11:41:50 -07:00
Kristiyan Kostadinov
1866bf5d61 refactor(compiler-cli): remove more unused code
Cleans up some more usages of TS factory APIs and some unused functions.
2026-03-10 10:57:30 -07:00
Andrew Scott
ba1508886d refactor(compiler-cli): Export hybrid_analysis symbols
Export symbols from hybrid_analysis from entrypoint
2026-03-10 10:18:36 -07:00
Andrew Scott
6bd2e7f703 refactor(compiler-cli): Export more things needed by external TCB generation
There are more things needed by external TCB generation tools
2026-03-09 16:58:48 -07:00
Kristiyan Kostadinov
82b758e934 refactor(compiler-cli): replace typescript usage in type reference emits
Replaces our usage of TypeScript APIs in several places that emit references to type nodes. Also deletes some unused code.
2026-03-09 11:22:53 -07:00
Andrew Scott
4f5c075d92 refactor(compiler-cli): export classpropertymapping from private
ClassPropertyMapping is used by the tcb_adapter so would be needed by external
TCB generation tools
2026-03-06 12:12:45 -08:00
Andrew Scott
ac8418d728 refactor(compiler-cli): export TCB types and methods
exports methods and types required for TCB generation. This would allow external
tools to generate TCBs using their own analysis pipelines, separate from the
compiler-cli implementations.
2026-03-05 14:35:47 -08:00
Andrew Scott
8217ef9b24 refactor(compiler-cli): abstract type check block metadata to be AST-free
This commit refactors the template type checking metadata interfaces to use detached, serializable metadata rather than retaining direct references to ts.Node or ts.Declaration instances.

A new tcb_adapter translates traditional TypeScript AST-bound metadata into these decoupled structures. This abstraction lays the groundwork for supporting native preprocessors (such as Rust or ts-go) which serialize metadata over JSON rather than passing live TypeScript objects.

Key changes:
- Introduced TcbDirectiveMetadata, TcbComponentMetadata, TcbReferenceMetadata, and TcbPipeMetadata to replace TypeCheckableDirectiveMeta where appropriate.
- Substituted deep TS compilation AST references with string module names and source spans to preserve out-of-band diagnostic capabilities.
- Detached generic typeParameters and transformType properties into synthesized, standalone TS mappings.
- Updated generateTypeCheckBlock and corresponding Operations to consume the new metadata.
2026-03-05 13:31:36 -08:00
Doug Parker
dc4cf649b6 fix(compiler-cli): ignore generated ngDevMode signal branch for code coverage
The Angular compiler unconditionally adds a debug name transform for signals
which generates a conditional on `ngDevMode` (e.g., `ngDevMode ? { debugName: "xyz" } : []`).
During testing, `ngDevMode` is true, so the true branch executes but the
false branch is never executed. Consequently, coverage tools report the
false branch as an untested line/branch, preventing 100% test coverage.

This commit adds a synthetic `/* istanbul ignore next */` comment to the
generated false branch so that Istanbul ignores it. We only include the
istanbul comment (instead of additionally including c8) to focus on the
established standard for Angular CLI/Karma coverage while maintaining
compatibility with modern Vitest setups, since @vitest/coverage-v8 now
natively respects the fallback istanbul comment.

Fixes #64583
2026-03-04 14:42:53 -08:00
Kristiyan Kostadinov
2c87f21abe fix(compiler-cli): always parenthesize object literals in TCB
This is a follow-up to #67381 which introduced a subtle bug where depending on the type checking configuration, we may put an object literal directly in the TCB body which the TS compiler ends up interpreting as a block. These changes resolve the issue by always wrapping the literal in parentheses.
2026-03-04 08:00:00 -08:00
SkyZeroZx
98eb24cea0 feat(core): Support optional timeout for idle deferred triggers
Allows specifying a timeout parameter for idle-based deferred triggers, enabling more granular control over when deferred actions are executed.

Closes angular#67187
2026-03-04 07:57:30 -08:00