Commit graph

418 commits

Author SHA1 Message Date
Alex Rickabaugh
0072eb48ba feat(compiler-cli): initial implementation of standalone components (#44812)
This commit implements the first phase of standalone components in the Angular
compiler. This mainly includes the scoping rules for standalone components
(`@Component({imports})`).

Significant functionality from the design is _not_ implemented by this PR,
including:

* imports of standalone components into NgModules.
* the provider aspect of standalone components

Future commits will address these issues, as we proceed with the design of
this feature.

PR Close #44812
2022-02-03 08:55:25 -08:00
Doug Parker
85ba38aecb refactor(compiler): add @suppress {msgDescriptions} if no description is present on an i18n message (#44787)
Refs http://b/214103351.

This happens if a user writes `<span i18n>Message</span>`. This is accepted as an internationalized message, but without a description. JSCompiler will throw an error in this situation because descriptions are generally required. Now, the Angular compiler will generate a suppression annotation so JSCompiler allows the syntax. This will ease an internal migration to JSCompiler-based i18n.

PR Close #44787
2022-02-02 15:33:44 -08:00
JoostK
6763967151 refactor(compiler): remove ViewEngine identifiers (#44676)
This commit removes the leftover `Identifiers` class that was used in the
ViewEngine compiler. The remaining usages of the `inlineInterpolate` and
`interpolate` instructions were refactored to make use of an
`InterpolationExpression` output expression to capture the argument list of an
interpolation expression. An attempt was made to refactor this further by
converting to the desired interpolation instruction immediately, but some
downstream consumers are designed in a way where the argument list itself is
needed, e.g. as other arguments need to be prepended/appended.

PR Close #44676
2022-02-02 00:04:13 +00:00
JoostK
1f6249dae8 refactor(compiler): remove directive matching from template compiler (#44731)
The directive matching pass that happens during template compilation is
redundant, since directive matching has already happened during the resolution
phase of ngtsc and only matching declarables are provided to the template
compiler. In JIT mode the declarables only become available after the primary
template compilation has completed, so there is no need to perform directive
matching in both JIT and AOT mode.

PR Close #44731
2022-01-18 14:51:08 -08:00
ivanwonder
73424def13 feat(compiler-cli): provide the animations for DirectiveMeta (#44630)
In `language-service`, the `checker.getDirectiveMetadata` doesn't return the animations meta of the `Component`.
but it's useful for animation completion.

PR Close #44630
2022-01-10 21:22:44 +00:00
JoostK
f40802f1bd refactor(compiler): remove unused unsupported function (#44411)
This function is no longer used so is being removed.

PR Close #44411
2022-01-04 15:54:10 -08:00
JoostK
f86e02e01e refactor(compiler): cleanup distinction in parse logic (#44411)
This removes the special casing of parse-validation logic that was only
used by Ivy.

PR Close #44411
2022-01-04 15:54:10 -08:00
JoostK
a758b8866e refactor(compiler): remove BindingForm enum (#44411)
The Ivy compiler only uses `BindingForm.Expression`, so all other
variants are removed.

PR Close #44411
2022-01-04 15:54:10 -08:00
JoostK
da159a5144 refactor(compiler): cleanup AST fixup of listener instructions (#44411)
This commit refactors the generation of listener instructions to no
longer fixup the output AST that was designed for ViewEngine.

PR Close #44411
2022-01-04 15:54:09 -08:00
JoostK
e8812bc04e refactor(compiler): cleanup unsafe usage of null value for ng-content selector (#44411)
This commit improves the null-safety of the ng-content selector and
updates a comment that turned out to be slightly inaccurate.

Closes #38407

PR Close #44411
2022-01-04 15:54:09 -08:00
Alex Rickabaugh
43db24302c refactor(compiler): delete View Engine components of @angular/compiler (#44368)
This commit finishes the removal of View Engine from the codebase, deleting
those pieces of @angular/compiler which were only used for VE.

Co-Authored-By: JoostK <joost.koehoorn@gmail.com>

PR Close #44368
2021-12-06 13:12:36 -05:00
dario-piotrowicz
6ae38584b0 docs(core): improve viewEncapsulation documentation (#44151)
Slighlty improve the `viewEncapsulation` documentation (both in code
comments and content files) to make it more clear and understandable.

See https://github.com/angular/angular/pull/44099#discussion_r745890903

PR Close #44151
2021-11-24 18:53:45 +00:00
Pete Bacon Darwin
393efa54e6 fix(compiler): ensure that partially compiled queries can handle forward references (#44113)
When a partially compiled component or directive is "linked" in JIT mode, the body
of its declaration is evaluated by the JavaScript runtime. If a class is referenced
in a query (e.g. `ViewQuery` or `ContentQuery`) but its definition is later in the
file, then the reference must be wrapped in a `forwardRef()` call.

Previously, query predicates were not wrapped correctly in partial declarations
causing the code to crash at runtime. In AOT mode, this code is never evaluated
but instead transformed as part of the build, so this bug did not become apparent
until Angular Material started running JIT mode tests on its distributable output.

This change fixes this problem by noting when queries are wrapped in `forwardRef()`
calls and ensuring that this gets passed through to partial compilation declarations
and then suitably stripped during linking.

See https://github.com/angular/components/pull/23882 and https://github.com/angular/components/issues/23907

PR Close #44113
2021-11-10 18:25:16 +00:00
Andrew Kushnir
60f3b33b4b Revert "fix(compiler): support i18n interpolated only attribute bindings (#43815)" (#43882)
This reverts commit bba0a87055.

The reason for rollback: this change is breaking some targets in Google's codebase when there is no attribute value is displayed (attr.aria-label) when translated.

PR Close #43882
2021-10-18 13:15:57 -07:00
Pete Bacon Darwin
bba0a87055 fix(compiler): support i18n interpolated only attribute bindings (#43815)
While fully dynamic bound properties (and attributes) cannot be marked for localization, properties that only contain interpolation can.

This commit ensure that attribute bindings that only contain interpolation can also be marked for localization.

Closes #43260

PR Close #43815
2021-10-18 09:24:39 -07:00
Pete Bacon Darwin
c85bcb0c63 feat(compiler): reference ICU message IDs from their placeholders (#43534)
When extracting i18n messages from templates, ICU messages are split out from the
message that contains them. This can make it difficult in the translation files to match up
the two messages, especially if the ICU is reused in multiple placeholders.

This commit builds on top of the previous one to expose the message ID of ICU messages
from the ICU placeholders as additional metadata in the `$localize` tagged strings.
Now the metablock following any placeholder can also contain the associated ID
delimited from the placeholder name by `@@`.

Fixes #17506

PR Close #43534
2021-10-18 09:23:59 -07:00
Kristiyan Kostadinov
2028c3933f refactor(compiler): combine call ASTs (#42882)
Currently the compiler has three different classes to represent a "call to something":
1. `MethodCall` - `foo.bar()`
2. `SafeMethodCall` - `foo?.bar()`.
3. `FunctionCall` - Any calls that don't fit into the first two classes. E.g. `foo.bar()()`.

There are a few problems with this approach:
1. It is inconistent with the TypeScript AST which only has one node: `CallExpression`.
2. It means that we have to maintain more code, because the various parts of the compiler need to know about three node types.
3. It doesn't allow us to easily implement some new JS features like safe calls (e.g. `foo.bar?.())`).

These changes rework the compiler so that it produces only one node: `Call`. The new node behaves  similarly to the TypeScript `CallExpression` whose `receiver` can be any expression.

There was a similar situation in the output AST where we had an `InvokeMethodExpression` and `InvokeFunctionExpression`. I've combined both of them into `InvokeFunctionExpression`.

PR Close #42882
2021-09-21 20:55:29 +00:00
Pete Bacon Darwin
feba4d2719 fix(compiler): include leading whitespace in source-spans of i18n messages (#43132)
Previously, the way templates were tokenized meant that we lost information
about the location of interpolations if the template contained encoded HTML
entities. This meant that the mapping back to the source interpolated strings
could be offset incorrectly.

Also, the source-span assigned to an i18n message did not include leading
whitespace. This confused the output source-mappings so that the first text
nodes of the message stopped at the first non-whitespace character.

This commit makes use of the previous refactorings, where more fine grain
information was provided in text tokens, to enable the parser to identify
the location of the interpolations in the original source more accurately.

Fixes #41034

PR Close #43132
2021-09-16 18:15:51 +00:00
Pete Bacon Darwin
c32bfe5860 refactor(compiler): remove cyclic dependencies (#43129)
This commit removes 9 cycles in the dependency graph of the compiler code.

PR Close #43129
2021-08-16 13:07:23 -07:00
atscott
9436f4bf77 Revert "refactor(compiler): remove cyclic dependencies (#42062)" (#43033)
This reverts commit 75855196e3.

PR Close #43033
2021-08-03 15:38:54 -07:00
atscott
dd82bbfa27 Revert "fix(compiler): include leading whitespace in source-spans of i18n messages (#42062)" (#43033)
This reverts commit f08516db09.

PR Close #43033
2021-08-03 15:38:54 -07:00
Pete Bacon Darwin
f08516db09 fix(compiler): include leading whitespace in source-spans of i18n messages (#42062)
Previously, the way templates were tokenized meant that we lost information
about the location of interpolations if the template contained encoded HTML
entities. This meant that the mapping back to the source interpolated strings
could be offset incorrectly.

Also, the source-span assigned to an i18n message did not include leading
whitespace. This confused the output source-mappings so that the first text
nodes of the message stopped at the first non-whitespace character.

This commit makes use of the previous refactorings, where more fine grain
information was provided in text tokens, to enable the parser to identify
the location of the interpolations in the original source more accurately.

Fixes #41034

PR Close #42062
2021-08-02 09:53:13 -07:00
Pete Bacon Darwin
75855196e3 refactor(compiler): remove cyclic dependencies (#42062)
This commit removes 9 cycles in the dependency graph of the compiler code.

PR Close #42062
2021-08-02 09:53:12 -07:00
Paul Gschwendtner
96c93260a2 refactor(compiler): ensure compatibility with noImplicitOverride (#42512)
Adds the `override` keyword to the `compiler` sources to ensure
compatibility with `noImplicitOverride`.

PR Close #42512
2021-07-12 13:11:14 -07:00
Kristiyan Kostadinov
404c8d0d88 fix(compiler): incorrect context object being referenced from listener instructions inside embedded views (#42755)
Currently unless a listener inside of an embedded view tries to reference something from the parent view, or if the reference is a local ref, we don't generate the view restoration instructions and we allow for the value to be picked up from the context object in the function parameters. The problem is that the listener is only run during creation mode and the context object may have been swapped out afterwards.

These changes fix the issue by always generating the view restoration instructions for listeners inside templates.

Fixes #42698.

PR Close #42755
2021-07-12 11:58:18 -07:00
Kristiyan Kostadinov
f52df99fe3 fix(compiler): generate view restoration for keyed write inside template listener (#42603)
If an implcit receiver is accessed in a listener inside of an `ng-template`, we generate some extra code in order to ensure that we're assigning to the correct object. The problem is that the logic wasn't covering keyed writes which caused it to write to the wrong object and throw an assertion error at runtime.

These changes expand the logic to cover keyed writes.

Fixes #41267.

PR Close #42603
2021-06-21 18:30:37 +00:00
Kristiyan Kostadinov
73824d5337 fix(compiler): not generating update instructions for ng-template inside alternate namespaces (#41669)
We have a check that determines whether to generate property binding instructions for an `ng-template`. The check looks at whether the tag name is exactly `ng-template`, but the problem is that if the tag is placed in a non-HTML namespace (e.g. `svg`), the tag name will actually be `:namespace:ng-template` and the check will fail.

These changes resolve the issue by looking at the tag name without the namespace.

Fixes #41308.

PR Close #41669
2021-04-20 09:44:44 -07:00
Paul Gschwendtner
c855bf4c56 refactor(compiler): clean up template information passed for partial compilation (#41583)
With the introduction of the partial compilation, the Angular compiler's
existing `parseTemplate` method has been extended to pass through multiple
properties purely in favor of the partial compilation.

e.g. the `parseTemplate` function now accepts an "option" called `isInline`.
This option is just passed through and returned as part of the `ParsedTemplate`.

This is not ideal because the `parseTemplate` function doesn't care
whether the specified template was inline or not. This commit cleans
up the `parseTemplate` compiler function so that nothing needed only
for the partial compilation is added to it.

We introduce a new struct for additional template information that
is specific to the generation of the `declareComponent` function. With
that change, we can simplify the component decorator handler and keep
logic more local.

PR Close #41583
2021-04-16 09:33:05 -07:00
Pete Bacon Darwin
71d3b24da3 refactor(compiler): fix typo (#41316)
There was  spelling mistake in a comment.

PR Close #41316
2021-04-07 13:57:12 -07:00
Kristiyan Kostadinov
e112e320bf fix(compiler): handle case-sensitive CSS custom properties (#41380)
Currently we normalize all CSS property names in the `StylingBuilder` which breaks custom properties, because they're case-sensitive. These changes add a check so that custom properties aren't normalized.

Fixes #41364.

PR Close #41380
2021-03-30 16:57:44 -07:00
James Henry
5e46901ffc refactor(compiler): option to include html comments in ParsedTemplate (#41251)
Adds a `collectCommentNodes` option on `ParseTemplateOptions` which will cause the returned `ParsedTemplate` to include an array of all html comments found in the template.

PR Close #41251
2021-03-29 15:16:26 -07:00
Pete Bacon Darwin
88683702e5 refactor(core): rename ...WithMeta types to ...Declaration and alias to unknown (#41119)
These types are only used in the generated typings files to provide
information to the Angular compiler in order that it can compile code
in downstream libraries and applications.

This commit aliases these types to `unknown` to avoid exposing the
previous alias types such as `ɵɵDirectiveDef`, which are internal to
the compiler.

PR Close #41119
2021-03-22 08:57:18 -07:00
Andrew Kushnir
3a55698402 fix(core): remove obsolete check for [class] and [className] presence (#41254)
Previously presence of both [class] and [className] bindings on an element was treated as compiler error (implemented in 6f203c9575). Later, the situation was improved to actually allow both bindings to co-exist (see a153b61098), however the compiler check was not removed completely. The only situation where the error is thrown at this moment is when static (but with interpolation) and bound `class` attributes are present on an element, for ex.:

```
<div class="{{ one }}" [class]="'two'"></div>
```

In the current situation the error is acually misleading (as it refers to `[className]`).

This commit removes the mentioned compiler check as obsolete and makes the `class` and `style` attribute processing logically the same (the last occurrence is used to compute the value).

PR Close #41254
2021-03-19 12:37:45 -07:00
Pete Bacon Darwin
8a33842cca refactor(compiler): consolidate R3CompiledExpression (#41080)
There were a number of almost identical interfaces used in
the same way throughout the Render3 compiler code.
This commit changes the compiler to use the same interface
throughout.

PR Close #41080
2021-03-15 13:26:51 -07:00
Igor Minar
9c210281d4 feat(compiler): emit @__PURE__ or @pureOrBreakMyCode annotations in the generated code (#41096)
This change marks all relevant define* callsites as pure, causing the compiler to
emmit either @__PURE__ or @pureOrBreakMyCode annotation based on whether we are
compiling code annotated for closure or terser.

This change is needed in g3 where we don't run build optimizer but we
need the code to be annotated for the closure compiler.

Additionally this change allows for simplification of CLI and build optimizer as they
will no longer need to rewrite the generated code (there are still other places where
a build optimizer rewrite will be necessary so we can't remove it, we can only simplify it).

PR Close #41096
2021-03-08 10:30:08 -08:00
Pete Bacon Darwin
89563442b8 refactor(compiler): remove unused emitAllPartialModules() and associated code (#41040)
This method does not appear to be used in the project.
This commit removes it and code that it exclusively
depended upon, or depended upon it.

PR Close #41040
2021-03-04 11:04:26 -08:00
Andrew Scott
0847a0353b fix(language-service): Always attempt HTML AST to template AST conversion for LS (#41068)
The current logic in the compiler is to bail when there are errors when
parsing a template into an HTML AST or when there are errors in the i18n
metadata. As a result, a template with these types of parse errors
_will not have any information for the language service_. This is because we
never attempt to conver the HTML AST to a template AST in these
scenarios, so there are no template AST nodes for the language service
to look at for information. In addition, this also means that the errors
are never displayed in the template to the user because there are no
nodes to map the error to.

This commit adds an option to the template parser to temporarily ignore
the html parse and i18n meta errors and always perform the template AST
conversion. At the end, the i18n and HTML parse errors are appended to
the returned errors list. While this seems risky, it at least provides
us with more information than we had before (which was 0) and it's only
done in the context of the language service, when the compiler is
configured to use poisoned data (HTML parse and i18n meta errors can be
interpreted as a "poisoned" template).

fixes angular/vscode-ng-language-service#1140

PR Close #41068
2021-03-03 21:13:58 +00:00
Andrew Scott
54b088967a refactor(compiler): remove unreachable code (#40984)
1. The error function throws, so no code after it is reachable.
2. Some switch statements are exhaustive, so no code after them are reachable.

PR Close #40984
2021-03-01 15:29:20 -08:00
Kristiyan Kostadinov
cdf1ea1951 refactor(compiler): retrieve variables from context inside nested template listener (#40833)
This is a pre-requisite for #40360. Given the following template which has a listener
that references a variable from a parent template (`name`):

```
<ng-template let-name="name">
  <button (click)="hello(name)"></button>
</ng-template>
```

We generate code that looks that looks like. Note how we access `name` through `ctx`:

```js
function template(rf, ctx) {
  if (rf & 1) {
    const r0 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "button", 2);
    ɵɵlistener("click", function() {
      ɵɵrestoreView(r0);
      const name_r0 = ctx.name; // Note the `ctx.name` access here.
      const ctx_r1 = ɵɵnextContext();
      return ctx_r1.log(name_r0);
    });
    ɵɵelementEnd();
  }
}
```

This works fine at the moment, because the template context object can't be changed after creation.
The changes in #40360 allow for the object to be changed, which means that the `ctx` reference
inside the listener will be out of date, because it was bound during creation mode.

This PR aims to address the issue by accessing the context inside listeners through the saved
view reference. With the new code, the generated code from above will look as follows:

```js
function template(rf, ctx) {
  if (rf & 1) {
    const r0 = ɵɵgetCurrentView();
    ɵɵelementStart(0, "button", 2);
    ɵɵlistener("click", function() {
      const restoredCtx = ɵɵrestoreView(r0);
      const name_r0 = restoredCtx.name;
      const ctx_r1 = ɵɵnextContext();
      return ctx_r1.log(name_r0);
    });
    ɵɵelementEnd();
  }
}
```

PR Close #40833
2021-02-17 11:45:46 -08:00
Pete Bacon Darwin
322951af49 refactor(compiler-cli): error on cyclic imports in partial compilation (#40782)
Our approach for handling cyclic imports results in code that is
not easy to tree-shake, so it is not suitable for publishing in a
library.

When compiling in partial compilation mode, we are targeting
such library publication, so we now create a fatal diagnostic
error instead of trying to handle the cyclic import situation.

Closes #40678

PR Close #40782
2021-02-17 06:53:38 -08:00
Pete Bacon Darwin
9cb43fb507 refactor(compiler-cli): implement ɵɵngDeclarePipe() (#40803)
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial
compilation, and processing of those calls in the linker and JIT compiler.

See #40677

PR Close #40803
2021-02-12 09:00:16 -08:00
Alex Rickabaugh
bd0d19141b fix(compiler-cli): preserve user line endings in diagnostic template parse (#40597)
Normally the template parsing operation normalizes all template line endings
to '\n' only. This normalization operation causes source mapping errors when
the original template uses '\r\n' line endings.

The compiler already parses templates again to create a "diagnostic"
template AST with accurate source maps, to avoid other parsing issues that
affect source map accuracy. This commit configures this diagnostic parse to
also preserve line endings.

PR Close #40597
2021-01-29 11:15:16 -08:00
Misko Hevery
d516113803 refactor(core): Remove the need for explicit static query instruction (#40091)
Because the query now has `flags` which specify the mode, the static query
instruction can now be remove. It is simply normal query with `static` flag.

PR Close #40091
2021-01-14 13:55:02 -08:00
Misko Hevery
e32b6256ce fix(core): QueryList should not fire changes if the underlying list did not change. (#40091)
Previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail and it should not be the thing which determines
how often change event should fire.

This change introduces a new `emitDistinctChangesOnly` option for
`ContentChildren` and `ViewChildren`.

```
export class QueryCompWithStrictChangeEmitParent {
  @ContentChildren('foo', {
    // This option will become the default in the future
    emitDistinctChangesOnly: true,
  })
  foos!: QueryList<any>;
}
```

PR Close #40091
2021-01-14 13:55:02 -08:00
Pete Bacon Darwin
e7c3687936 refactor(compiler): synthesize external template node for partial compilation (#40237)
When partially compiling a component with an external template, we must
synthesize a new AST node for the string literal that holds the contents of
the external template, since we want to source-map this expression directly
back to the original external template file.

PR Close #40237
2021-01-07 13:12:53 -08:00
JoostK
d4327d51d1 feat(compiler-cli): JIT compilation of component declarations (#40127)
The `ɵɵngDeclareComponent` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareComponent` which invokes the JIT compiler
using the declaration object, such that a compiled component definition
is made available to the Ivy runtime.

PR Close #40127
2021-01-06 08:28:03 -08:00
Bjarki
6a9d7e5969 refactor(core): express trusted constants with tagged template literals (#40082)
The trustConstantHtml and trustConstantResourceUrl functions are only
meant to be passed constant strings extracted from Angular application
templates, as passing other strings or variables could introduce XSS
vulnerabilities.

To better protect these APIs, turn them into template tags. This makes
it possible to assert that the associated template literals do not
contain any interpolation, and thus must be constant.

Also add tests for the change to prevent regression.

PR Close #40082
2021-01-05 13:56:57 -08:00
JoostK
9186f1feea feat(compiler-cli): JIT compilation of directive declarations (#40101)
The `ɵɵngDeclareDirective` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareDirective` which invokes the JIT compiler
using the declaration object, such that a compiled directive definition
is made available to the Ivy runtime.

PR Close #40101
2020-12-23 09:52:19 -08:00
Andrew Kushnir
caa4666335 fix(compiler): avoid duplicate i18n blocks for i18n attrs on elements with structural directives (#40077)
Currently when `ɵɵtemplate` and `ɵɵelement` instructions are generated by compiler, all static attributes are
duplicated for both instructions. As a part of this duplication, i18n translation blocks for static i18n attributes
are generated twice as well, causing duplicate entries in extracted translation files (when Ivy extraction mechanisms
are used). This commit fixes this issue by introducing a cache for i18n translation blocks (for static attributes
only).

Also this commit further aligns `ɵɵtemplate` and `ɵɵelement` instruction attributes, which should help implement
more effective attributes deduplication logic.

Closes #39942.

PR Close #40077
2020-12-15 13:40:09 -08:00
Alex Rickabaugh
c55bf4a4a3 refactor(compiler-cli): identify structural directives (#40032)
This commit introduces an `isStructural` flag on directive metadata, which
is `true` if the directive injects `TemplateRef` (and thus is at least
theoretically usable as a structural directive). The flag is not used for
anything currently, but will be utilized by the Language Service to offer
better autocompletion results for structural directives.

PR Close #40032
2020-12-14 12:08:41 -08:00