3973 Commits

Author SHA1 Message Date
leonsenft afe8499a14 fix(compiler-cli): default template diagnostic related message source file to template
For external templates (using `templateUrl`), primary diagnostics are
reported against the synthetic `ts.SourceFile` representing the HTML
template document. However, secondary related messages (such as those in
`foreign_component.ts` and `oob.ts`) were explicitly passing the
component's TypeScript file as `sourceFile`.

Because the character offsets (`start` and `end`) originate from the
HTML template AST, associating them with the TypeScript source file
caused IDEs and CLI diagnostics to map HTML offsets onto the `.ts` file,
resulting in corrupt or out-of-bounds source locations.

This commit resolves the issue by:
1. Making `sourceFile` optional in `makeTemplateDiagnostic` and related
   checker interfaces (`TemplateTypeChecker`, `TemplateContext`).
2. Defaulting `relatedMessage.sourceFile` to the template's source file
   (`sf` for external/indirect templates, or the component `.ts` file
   for direct inline templates) when not explicitly provided.
3. Removing explicit `sourceFile: this.sourceMapping.node.getSourceFile()`
   mappings from `foreign_component.ts` and DOM element checks in
   `oob.ts`, allowing them to automatically resolve to the template file.
4. Adding unit test coverage for external templates encountering foreign
   component conflicts with related messages.

(cherry picked from commit a46292af26)
2026-08-25 16:19:36 -07:00
root 55eeb46418 fix(compiler-cli): retain metadata for strict standalone errors
This fix ensures that metadata is properly retained when processing
strict standalone component errors for improved error diagnostics.

(cherry picked from commit 74b294cd51)
2026-08-25 09:54:10 -07:00
Matthieu Riegler 079a846263 fix(compiler-cli): Produce correct tcb expression for optional chaining
The semantics of optional chaining changes when there are extra parenthesis. We need to make sure that we do not introduce some unnecessary ones.

fixes #70143

(cherry picked from commit e9ba39d671)
2026-08-24 15:21:22 -07:00
Kristiyan Kostadinov df00ed264c refactor(compiler-cli): add compiler option for enabling source locations
Adds an internal config options that allows us to enable source locations.

(cherry picked from commit f3c093df24)
2026-08-21 11:45:34 -07:00
Matthieu Riegler 83450d2924 fix(forms): report forbidden 2way bindings on when FormField is applied
We were already reporting regular bindings but not 2way.

fixes #70219

(cherry picked from commit c819880b91)
2026-08-19 00:08:05 +00:00
Kristiyan Kostadinov 44137117b3 fix(core): replace all hasOwnProperty usages with Object.hasOwn
We keep getting PRs that target single usages of `hasOwnProperty` and we have ~100 of them. These changes aim to address the issue centrally by swapping out all the instances and adding a lint rule against introducing new ones.

(cherry picked from commit 732e505018)
2026-08-18 16:17:23 +00:00
splincode 1e53aa0b38 refactor: correct typos in comments, docs, and error messages
Fix misspellings found across multiple packages:

- `paramters` → `parameters` (utils.spec.ts)
- `directve` → `directive` (typecheck/context.ts)
- `subscriper` → `subscriber` (zone.js rxjs test)
- `swich` → `switch` (adev animation parser test)
- `subscribtion` → `subscription` (forms/abstract_model.ts)
- `lifecyle` → `lifecycle` (ng-devtools-backend hooks)
- `compatability` → `compatibility` (tree-visualizer.ts)
- `indentifier(s)` → `identifier(s)` (compiler-cli shared.ts, i18n_helpers.ts, declaration_only_emission_spec.ts)
- `identifer` → `identifier` (platform-browser shared_styles_host.ts)
- `prcess` → `process` (standalone-migration to-standalone.ts)

(cherry picked from commit d35c17d393)
2026-08-17 21:57:09 +00:00
Jaime Burgos 9d8aa3a829 refactor(compiler-cli): add error guide links to diagnostics
Add the error guide URL when a compiler diagnostic uses a negative
marked error code.

(cherry picked from commit 45ebb127e3)
2026-08-17 20:58:16 +00:00
Andrew Scott e9660b1801 fix(compiler-cli): correctly resolve symbol for SafePropertyRead in chained optional navigation
When resolving template symbols for SafePropertyRead in TCBs emitted with optional chaining (strictSafeNavigationTypes: true), SymbolBuilder falls back to finding a TS node matching the AST expression's nameSpan. It then traverses up through parent nodes to find the enclosing expression.

Previously, the traversal loop checked isAccessExpression(node.parent) without verifying whether node was the accessed member name or the expression receiver. When multiple optional navigation expressions are chained (e.g. route?.data?.['icon']), the parent of ((route)?.data) is an access expression where ((route)?.data) is the receiver. Because isAccessExpression was true, the loop continued ascending into the outer access expression, causing symbol resolution for data to erroneously return the symbol and TCB location of icon.

This commit refines the parent traversal condition so that it only climbs into a parent PropertyAccessExpression if node is the accessed name (node.parent.name === node), preventing escape into outer receiver expressions.

(cherry picked from commit e8aa222e7d)
2026-08-12 23:11:27 +00:00
Matthieu Riegler bb7f051631 refactor(compiler): remove explicit strict: true
This flag is set by default in TS 6.0

(cherry picked from commit f1c0c405c9)
2026-08-12 18:03:57 +00:00
Matthew Beck ec6deea513 fix(compiler-cli): record class extends clause references in DeferredSymbolTracker
`DeferredSymbolTracker.lookupIdentifiersInSourceFile` prunes `ts.isTypeNode`
subtrees so that references appearing exclusively inside type annotations
do not keep static import declarations in the emitted JavaScript.

However, `ts.isTypeNode` returns `true` for `ts.ExpressionWithTypeArguments`,
which TypeScript uses to represent both `extends` and `implements` heritage
clauses. An `extends` clause on a class declaration or class expression is a
value position that survives in the emitted JavaScript output.

Because `isTypeNode` returned `true`, references to base classes imported
alongside deferred dependencies were ignored. As a result, the compiler
erroneously marked the static import statement as deferrable and deleted it
from the emitted JavaScript, leaving the `extends <Base>` clause referencing
an undeclared identifier and causing a runtime `ReferenceError`.

This commit ensures that `ExpressionWithTypeArguments` under a class `extends`
clause is not treated as an erasable type node, preserving the static import
whenever a base class is referenced.

(cherry picked from commit 8d6c925392)
2026-08-07 23:10:45 +00:00
Matthieu Riegler 76dff307b4 fix(compiler): Generate correct expression for optional chaning.
Optional chaining was generating expressions with included an extra pair of parenthesis which changed the semantics of the expression and threw an unexpected error from the optional chain non nullable extended diagnostic.

fixes #70085

(cherry picked from commit d7b03f5523)
2026-08-07 22:55:13 +00:00
Matthew Beck b569f6e82b test(compiler-cli): add compliance case for @HostListener on a property
`@HostListener` is not limited to methods — it is equally valid on a property
holding a function, which is the idiomatic way to keep `this` bound:

    @HostListener('window:beforeunload', ['$event'])
    private onUnload = (event: BeforeUnloadEvent) => {...};

Every existing host-listener compliance case declares the handler as a method,
so the property form was uncovered. This adds a case exercising both a public
and a private function-valued property, one of them with a global (`window:`)
event target, and locks in the emitted chained `ɵɵlistener` calls plus
`ɵɵresolveWindow`.

Verified against all four compliance modes (full, partial/linked,
declaration-only); GOLDEN_PARTIAL.js regenerated via the golden update rule.

(cherry picked from commit d44b3224d9)
2026-07-29 08:52:58 -07:00
SkyZeroZx 23cf1a828b fix(core): sanitize host bindings on concrete hosts (#69558)
Host binding sanitization previously used the declaring directive or component selector to choose a compile-time security context. The same host binding can execute on a different concrete element through hostDirectives, inherited host bindings, dynamic directives, or createComponent hostElement usage.

Compute host binding security contexts against possible concrete hosts and defer URL versus ResourceURL selection to runtime when necessary. Resolve dynamic root host TNodes to their native tag before sanitizer and security-sensitive attribute checks.

Fixes angular#69550

PR Close #69558
2026-07-29 08:36:34 -07:00
Matthew Beck 1caafa6d8a test(compiler-cli): format compliance TEST_CASES.json with prettier
Reformats the TEST_CASES.json files touched by the following change so they
satisfy the repo's prettier check (short inputFiles/files arrays collapsed to a
single line). Pure formatting; the parsed JSON is unchanged. Split into its own
commit so the coverage change that follows is easy to review.

(cherry picked from commit 5245ca5ba7)
2026-07-24 13:55:37 -07:00
Matthew Beck eb3e480360 test(compiler-cli): cover DOM-only vs full instruction set across compilation modes
Adds a compliance case pinning the instruction-set selection for a
directive-free standalone component:

  - full compile: the compiler can prove the template has no directive
    dependencies, so it takes the DOM-only fast path
    (`ɵɵdomElementStart`/`ɵɵdomElementEnd`).
  - local compile: the compiler cannot inspect dependencies, so
    `hasDirectiveDependencies` is forced true and the full instruction
    set is emitted (`ɵɵelementStart`/`ɵɵelementEnd`).

This mode-dependent switch was previously only exercised incidentally by
the `foreign_component` case, which couples it with foreign-component
compilation. The new case isolates it.
2026-07-21 11:06:36 +02:00
cexbrayat 0ae6d81ed2 fix(core): preserve explicit input transform write type
If a directive has an input declared as `dismissible = input<boolean>(true, {transform: booleanAttribute});` then the following templates were not compiling:

```
<div directiveName dismissible="true"></div>
<div directiveName dismissible></div>
```

This commit fixes the issue, without breaking contravariant consumers.
2026-07-15 12:02:18 -07:00
LordKay-sudo ae0ec7315c fix(compiler-cli): re-tag SourceFiles after TsCreateProgramDriver.updateFiles()
TypeScript reuses SourceFile objects between old and new programs, so untagging the old program also untags shared files in the new program. Re-apply shim tags on the new program to prevent getSemanticDiagnostics() crashes with TS 5.5+.
2026-07-14 09:18:35 -07:00
Alan Agius 13d9cc36c0 refactor: remove obsolete @types/babel__core dependency
Remove the obsolete @types/babel__core dependency from packages/compiler-cli and packages/localize. This dependency is no longer needed as Babel v8 ships with its own built-in TypeScript definitions.
2026-07-13 08:13:13 -07:00
Matthew Beck 1fb4678207 Revert "fix(core): allow static attributes for explicit input transforms"
This reverts commit 9b9b0e93c9.

This broke g3. Not sure yet why it didn't break externally. We can
investigate and fix following this revert.
2026-07-09 17:58:22 -07:00
cexbrayat 9b9b0e93c9 fix(core): allow static attributes for explicit input transforms
This is a follow-up to #67997, which allowed explicit read generics with input transforms, such as `input<boolean>(false, {transform: booleanAttribute})`.

That fixed the declaration, but static template attributes like `dismissible="true"` and bare `dismissible` were still checked as strings against the read type. Allow the fallback write type to include static attribute strings so these template forms compile.
2026-07-09 12:28:25 -07:00
leonsenft 5bd00add07 fix(compiler): support foreign components inside control flow blocks (#69674)
Prepend generated view scope variables to `view.create` in addition to
`view.update` so that expressions evaluated during creation (such as
foreign component property bindings) can resolve context variables from
parent views when nested inside control flow blocks (`@if`, `@switch`,
`@for`). This is necessary to support binding properties to foreign
components inside control flow blocks.
reflect this broader behavior.)

PR Close #69674
2026-07-09 09:38:24 -07:00
leonsenft 2e442f7876 perf(compiler): do not emit tag name when control flow root is foreign component (#69674)
When a control flow block (`@if`, `@switch`, `@for`) contains a single
root element that is a foreign component, do not treat its name as a tag
name for the template container (`conditionalCreate`, `repeaterCreate`).

PR Close #69674
2026-07-09 09:38:24 -07:00
P4 eb2a8ff63f fix(compiler-cli): apply debugName transform to required signal queries
Transform assumed `.required` functions always take options as the first argument.
This is true for `input` and `model`, but not for `viewChild` and `contentChild`,
which take the same arguments as non-required versions.

Change the code to put options for signal queries in the right position,
causing debugName to be correctly generated for signal queries.
2026-07-07 11:05:22 -07:00
arturovt ab618bdc0f refactor(compiler-cli): use BindingType enum check in suffix-not-supported extended diagnostic
Replaces the `node.keySpan.toString().startsWith('attr.')` string allocation in the `suffixNotSupported` extended template check with an O(1) `node.type === BindingType.Attribute` enum comparison.

The diagnostic message string is also extracted to a module-level constant so it is created once at module load time instead of on every diagnostic emit.

Additionally, this change adds missing test coverage for the `.%` and `.em` suffixes, as well as for a plain `attr.` binding without a style suffix.

Measured with a 100-iteration microbenchmark before and after the change (MacBook Pro 2018, Intel CPU):

```ts
const start = performance.now();
for (let i = 0; i < 100; i++) {
  new ExtendedTemplateCheckerImpl(templateTypeChecker, program.getTypeChecker(),
    [suffixNotSupportedFactory], {}).getDiagnosticsForComponent(component);
}
console.log((performance.now() - start) / 100, 'ms/iter');
```

Before: `~0.24 ms/iter`
After: `~0.14 ms/iter` (~40% faster)
2026-07-07 10:05:05 -07:00
cexbrayat eac363e92e fix(compiler-cli): detect uninvoked signals in bound expressions using ternary
Extend the interpolated signal extended diagnostic to inspect ternary-bound expressions and report uninvoked signal reads in bound bindings.

```
<div [style.width]="width() ? 1 : width"></div>
```

where the false branch should invoke the signal as `width()`.
2026-07-07 10:01:49 -07:00
leonsenft a19c02706f refactor(compiler-cli): support foreign imports with isolated declarations
Previously, extracting foreign component imports relied on the partial
evaluator and semantic import resolution to locate declaration
references across files. This resolver-based approach is incompatible
with isolated declarations and local compilation, where cross-file type
information and full semantic resolution are unavailable.

Replace the resolver-based foreign import evaluation with a lightweight,
AST-based extraction mechanism (`extractForeignImportsFromAst`). This
allows the compiler to extract foreign component names and raw AST
expressions directly from syntax trees during the analysis phase without
requiring full type checking.

Additionally, simplify the `ForeignComponentMeta` interface by removing
the obsolete reference property and implement granular AST diagnostics
that provide actionable error messages and usage examples when invalid
expressions are passed to `foreignImports`.
2026-07-07 09:10:21 -07:00
Angular Robot 731d665a86 build: update babel monorepo to v8
See associated pull request for more information.
2026-07-06 14:05:15 -07:00
Matthieu Riegler 997b772f28 fix(compiler): use regular optional chaining expression for safe function calls in TCBs
Optional return types should not report non-nullable optional chaning on function calls.

fixes #69609
2026-07-06 14:02:40 -07:00
Matthew Beck 8c8b2f7783 feat(compiler): Support css var namespacing in properties (#68846)
Adds support for namespacing css variables in style properties. Behaves
as you'd expect following the implementation for stylesheets generally.

This change also moves the error message into a util function since we
now need to produce the same error in three places.

PR Close #68846
2026-07-06 13:36:24 -07:00
Matthew Beck f98547675c feat(compiler): Namespace CSS variables to the app (#68846)
Adds logic to inject symbols into CSS variables for runtime namespacing.
The runtime now replaces instances of `%NS%` with a namespacing
variable, limiting reach of CSS variables to the current app. An opt-out
syntax of a `--global` prefix allows users to avoid this behavior.

PR Close #68846
2026-07-06 13:36:24 -07:00
Andrew Scott a7bde662c3 refactor(core): allow AnimationClassBindingFn to return undefined or null
The AnimationClassBindingFn type was too restrictive, only allowing `string | string[]`. However, the runtime (`getClassListFromValue`) safely handles `undefined` and `null` values by treating them as no animation.

This change updates the type to allow `undefined` and `null`, which is consistent with other class/style bindings in Angular and avoids requiring workarounds (like empty strings) in host bindings.

Added a compliance test case to verify that `[animate.enter]` with a potentially `undefined` value compiles correctly.
2026-06-30 17:27:59 -07:00
Alex Rickabaugh a5f1b20373 Revert "fix(compiler-cli): include toSignal in debugName transform"
This reverts commit 165995285c. Reason: breaking
in g3 (ngDevMode not defined)
2026-06-30 13:24:17 -07:00
leonsenft a720094deb refactor(core): format @content blocks consistently (#69502)
`@content(name)` -> `@content (name)` to align with other block syntax.

PR Close #69502
2026-06-29 17:34:27 -07:00
Paweł Maniecki 165995285c fix(compiler-cli): include toSignal in debugName transform
the toSignal function received a debugName option in 0812ac3bec,
but was not covered by the signalMetadataTransform which sets the debugName in dev mode
automatically.
2026-06-29 14:32:17 -07:00
leonsenft 4847c0e07b refactor(core): enable foreign components to render content lazily
Transition parameterless `@content` projection in foreign components
from eager DOM creation to lazy evaluation. Previously, projecting
content into a foreign component eagerly instantiated the embedded view
and created DOM nodes, causing unnecessary resource consumption if the
content was hidden or unmounted.

With this change, runtime content instructions (`ɵɵforeignContent` and
`ɵɵforeignContentFn`) pass lazy producer callbacks directly through the
foreign component's configured `contentAdapter`. View creation and
teardown registration occur lazily when the external framework evaluates
the adapted producer.

`foreignImport` now requires a third argument, `contentAdapter`,
specifying how Angular content producer callbacks are adapted for the
target external framework.
2026-06-29 14:22:48 -07:00
aparziale 8b2785b597 fix(compiler-cli): report diagnostic instead of crashing on malformed host binding
`parseHostBindings` throws plain `Error`s for malformed host bindings
(e.g. a property binding with a non-static value, as can happen while
editing in the language service). These were uncaught during directive
analysis, crashing the compiler and the Angular Language Service.

Wrap the call and surface the error as a `FatalDiagnosticError` so it
becomes a diagnostic and analysis can complete normally.

Fixes #69106
2026-06-24 12:14:23 -04:00
Alex Rickabaugh 86ade07de6 refactor(compiler): add support for @Input transforms under isolatedDeclarations
Adds support for `@Input` transform functions in isolated declarations mode (`emitDeclarationOnly: true`), allowing components and directives to specify `transform` functions without triggering fatal compiler errors.

Synthesizes the `ngAcceptInputType_` write type syntactically:
- For referenced functions (`transform: booleanAttribute`), emits `Parameters<typeof booleanAttribute>[0]`, relying on downstream template type checking to resolve the type.
- For inline functions (`transform: (v: string) => boolean`), extracts `parameters[0].type` directly from the local TypeScript AST.
2026-06-16 10:27:18 -07:00
Alex Rickabaugh 5d2b1c4100 refactor(compiler): add support for host directives under isolatedDeclarations
Removes restrictions around using external references and local directives in `hostDirectives` under isolated declarations mode (`emitDeclarationOnly: true`).

By wrapping the host directive reference in a `WrappedNodeExpr`, TypeScript's declaration emitter seamlessly emits `typeof hostReference.node`, preserving existing imports or local identifiers exactly as authored. Also adds support for translating `PropertyAccessExpression` inside `WrappedNodeExpr` into `QualifiedName` for `.d.ts` emission, ensuring namespace imports (`import * as n from './dir'`) are preserved correctly.
2026-06-16 10:27:18 -07:00
SkyZeroZx 0152e3cbdf fix(core): treat iframe credentialless as security-sensitive
Mark the iframe `credentialless` attribute as security-sensitive so dynamic
bindings are handled consistently with other iframe attributes that affect the
initial navigation, such as `sandbox`, `allow`, `referrerPolicy`, `csp`, and
`fetchPriority`.

Because `credentialless` must be present before the iframe starts loading to
affect the navigation’s credential mode, late dynamic updates can leave the final
DOM looking correct while the initial request was not loaded credentiallessly.
2026-06-16 09:05:53 -07:00
Andrew Scott 83622ee519 refactor(compiler-cli): Export indexer API for use in hybrid analysis
exports indexer API for use in hybrid analysis
2026-06-15 11:53:36 -07:00
Andrew Scott 21fccd4038 refactor(compiler-cli): Change indexComponent file to be fileUrl
We do not need ParseSourceFile which contains the whole content. Only the file url is ever used.
2026-06-15 10:56:51 -07:00
Andrew Scott 2112edefe1 refactor(core): ɵɵgetInheritedFactory should accept abstract type
An abstract component or directive can extend another class, meaning
ɵɵgetInheritedFactory needs to allow abstract
2026-06-15 09:22:35 -07:00
Andrew Scott 8984c59626 refactor(core): ComponentDef should allow abstract types too
d1539a8513 incorrectly assumed components wouldn't be abstract but
it is still possible (though probably should be an abstract directive instead).
2026-06-11 13:08:09 -07:00
Andrew Scott d25d2e1524 refactor(core): Update registerNgModuleType to support codegen typechecking
Updates types and adds test for source->source transformation with tsc downstream
2026-06-10 10:52:55 -07:00
Andrew Scott d1539a8513 refactor(core): Fix DirectiveDefinition interface to allow abstract classes
Interface should permit abstract classes since directives can be abstract
2026-06-09 16:21:04 -07:00
SkyZeroZx 3c70270c96 fix(compiler): sanitize two-way properties
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.

Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.
2026-06-08 13:12:22 -07:00
leonsenft 11b206b919 fix(core): introduce disposal mechanism for Angular views in foreign @content
Coordinate template lifecycle events between Angular and foreign components to
allow clean teardown of nested Angular views inside a foreign container.

Previously, when Angular content was projected into a foreign component (for
instance, via render props), Angular had no way to receive destruction
notifications from the foreign component. If the foreign component unmounted
or conditionally removed its children, the nested Angular views remained active,
leading to memory leaks and incomplete lifecycle teardowns.

This change introduces the `ON_DESTROY` symbol and a new registration mechanism
(`ForeignOnDestroyFn`) on the `ForeignComponent` interface. The `foreignImport`
helper now takes an additional `onDestroy` callback function where the foreign
component can register to receive Angular's view-destruction callback.

During the creation phase, `ɵɵforeignContentFn` resolves the foreign component
from the constant pool using a new constant pool index and invokes the
`onDestroy` function. This registers a callback that destroys the corresponding
embedded view from the container.

In the compiler, `ForeignComponentOp` is modified to track the target constant
pool index, and `ForeignContentExpr` reification is updated to pass this index
to `ɵɵforeignContentFn`.
2026-06-08 10:17:40 -07:00
leonsenft 25c744c4d0 fix(compiler): support foreign components defined outside top-level scope
Currently, the template pipeline directly emits the raw expression for foreign
component definitions (such as `frameworkImport(MyComponent)`) directly into
the body of the generated template function. If a foreign component is defined
inside a local scope or is non-exported (e.g. nested inside a test block), the
emitted template function may not have access to that variable because
`ɵɵdefineComponent` and its template functions are emitted at the top-level
module scope. This previously caused reference errors during template
compilation.

This commit updates the compilation pipeline to instead ingest foreign
component references into the component's `consts` pool. The
`ɵɵforeignComponent` runtime instruction is updated to accept an index into the
constant pool rather than a raw expression. By routing the references through
the `consts` pool, block-scoped classes and variables are appropriately
captured by `ngtsc` without scoping errors, properly supporting nested/local
foreign component usage.
2026-06-08 10:17:40 -07:00
leonsenft b399f78c34 refactor(compiler): support passing @content blocks as functions
Previously, foreign component `@content` blocks were rendered eagerly by
Angular and could only project a list of nodes. With this change, `@content`
can be used to declare a function (e.g. `@content(renderItem; let item)`) that
is passed as a callback prop to the foreign component, allowing the foreign
component to invoke it with context arguments at its leisure.

Implementation details:
- Introduces a new runtime instruction `ɵɵforeignContentFn` which wraps the
  template function so it can be called on demand with arguments by the foreign
  component.
- Extends the compiler AST to parse and validate `@content` parameters.
- Maps `@content` parameters to the corresponding positional arguments of the
  calling foreign component function property.
2026-06-08 10:17:40 -07:00