Currently we have a `ParserError` that is used for the expression parser and a `ParseError` that is used everywhere else. These changes consolidate them into the `ParseError` to avoid confusion and make it easier to add more context in the future.
PR Close#62160
Currently our expression parser produces two different expressions for writes: `PropertyWrite` (e.g. `foo.bar = 123`) or `KeyedWrite` (e.g. `foo[0] = 123`). This is inconsistent with other ASTs, like TypeScript's, where writes are represented as binary expressions with a `=` operator and it makes it difficult to implement more write operators like `??=`, because we'd essentially have to duplicate them.
These changes switch the expression parser over to produce binary expressions instead.
PR Close#61682
When the expression parser consumes tokens inside a parenthesized expression, it looks for valid tokens until it hits and invalid one or a closing paren. If it finds an invalid token, it reports and error and tries to recover until it finds a closing paren. The problem is that in such cases, it would produce the `ParenthesizedExpression` and continue parsing **from** from the closing paren which would then produce more errors that add noise to the output and result in an incorrect representation of the user's code. E.g. `foo((event.target as HTMLElement).value)` would be recovered to `foo((event.target)).value` instead of `foo((event.target).value)`.
These changes resolve the issue by skipping over the closing paren at the recovery point.
Fixes#61792.
PR Close#61815
Currently we reuse the same binding parser for all expressions in the template. Under the hood, the parser has a single `errors` array that it passes into all ASTs which means that if there's one binding with an error, those errors will be propagated to all other ASTs in the template.
These changes switch to having a unique `errors` array for each AST so we only report errors once.
Relates to #61792.
PR Close#61793
When defer blocks have a reference-based trigger without a parameter, we infer it from the placeholder block. This requires some validations like ensuring that there's only one element in the placeholder. The validations are currently implemented at the parser level which can affect tools like linters that need to pass `preserveWhitespaces: true` in order to get accurate source mappings.
These changes move the validations into the template type checker so that they still get flagged, but much later in the process. Moving them over involves a bit more work, because the template type checker also sets `preserveWhitespaces: true`.
Fixes#61725.
PR Close#61747
Removes the following unused code from the compiler:
* The ICU expander appears to be some really old code converting ICUs into legacy-style control flow directives. It's annoying to keep this one since we need to update it any time the AST changes.
* The `PipeCollector` class wasn't used anywhere.
* The `partitionArray` function wasn't used anywhere.
* The `newArray` function was used only in one test and it can be easily replaced with `new Array().fill`.
PR Close#61668
These helpers are often imported by various tests throughout the
repository, but the helpers aren't exported/exposed from the public
entry-point; even though they confusingly reside in there.
This commit fixes this, and moves the helpers into
`packages/private/testing`. This is a preparation for the `ts_project`
migration where we don't want to leverage deep imports between packages.
PR Close#61472
Follow-up from https://github.com/angular/angular/pull/61240#discussion_r2084445328. Adds a `isSelfClosing` property on element-like AST nodes so consumers can easily determine if it's self-closing, rather than having to look at the spans. This is useful for migrations and in the language service.
PR Close#61307
We don't need this tooling anymore because we are already validating
that there are no circular dependencies via the `ng-dev` tooling that
checks `.ts` files directly.
Also these tests never actually failed to my knowledge.
PR Close#61156
Fixes that the template binder didn't resolve references to DOM nodes (e.g. `<div #ref></div>` if the matcher being passed in isn't a `SelectorMatcher`.
PR Close#61100
An earlier commit that introduced tracking of selectorless directives to the template binder made it so `getDirectivesOfNode` returns _all_ of the matched directives while a new method called `getOwnedDirectives` would return only the ones brought in by the specific node.
In hindsight, this is likely to cause bugs in the future, because it's unclear whether to reach for `getDirectivesOfNode` or `getOwnedDirectives`. These changes remove `getOwnedDirectives` and make it so in selectorless `getDirectivesOfNode` accepts the directive AST node itself.
Another goal of this refactor is that the TCB shouldn't have to check the `selectorlessEnabled` config option.
PR Close#61018
Updates the template binder to include information about directives owned by a specific component/directive node and the names of template symbols that don't exist. These will be used when generating the type check block.
PR Close#60977
Updates the template binder to account for the new selectorless AST nodes. This is a prerequisite to supporting template type checking of the new syntax.
PR Close#60952
Adds the follow validations to the selectorless template parsing:
* Local references with values are not allowed (e.g. `#foo="bar"`).
* Multiple local references with the same on a component or directive are not allowed.
PR Close#60952
Updates the target binder to allow either a selector-based or selectorless matcher to be passed in. This will allow us to skip some of the overhead when matching directives to nodes.
PR Close#60952
This commit adds the support for the `in` keyword as a relational operator, with the same precedence as the other relational operators (<,>, <=, >=)
BREAKING CHANGE: 'in' in an expression now refers to the operator
PR Close#58432
Now that the expression AST contains parenthesized expressions, this
refactors the template pipeline to strip out the ones we don't need.
PR Close#60169
Following up on #60127 which added the concept of a parenthesized
expression to the output AST, this does the same for the expression AST.
PR Close#60169
Add support for the `void` operator in templates and host bindings.
This is useful when binding a listener that may return `false` and
unintentionally prevent the default event behavior.
Ex:
```
@Directive({
host: { '(mousedown)': 'void handleMousedown()' }
})
```
BREAKING CHANGE: `void` in an expression now refers to the operator
Previously an expression in the template like `{{void}}` referred to a
property on the component class. After this change it now refers to the
`void` operator, which would make the above example invalid. If you have
existing expressions that need to refer to a property named `void`,
change the expression to use `this.void` instead: `{{this.void}}`.
PR Close#59894
Both `:host` and `:host-context` work by looking for a specific character sequence that is terminated by `,` or `{` and replacing selectors inside of it with scoped versions. This is implemented as a regex which isn't aware of things like nested selectors. Normally this is fine for `:host`, because each `:host` produces one scoped selector which doesn't affect any child selectors, however it breaks down with `:host-context` which replaces each instance with two selectors. For example, if we have a selector in the form of `:host-context(.foo) a:not(.a, .b)`, the compiler ends up determining that `.a,` is the end selector and produces `.foo[a-host] a[contenta]:not(.a, .foo [a-host] a[contenta]:not(.a, .b) {}`.
These changes resolve the issue by splitting the CSS alogn top-level commas, processing the `:host-context` in them individually, and stiching the CSS back together.
PR Close#59276
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
'parameter' was spelled as 'paramater'.
Fix spelling error in Update r3_control_flow.ts
'parameter' was spelled as 'paramater'.
Fix spelling error in r3_template_transform_spec.ts
'parameter' was spelled as 'paramater'.
PR Close#59289
fix transformation logic for `:where` and `:is` pseudo-selectors
when these selectors were used in a chain. results were often broken,
the last letter of the selector was incorrectly trimmed.
see tests for examples
Fixes#58226
PR Close#58681