Commit graph

1123 commits

Author SHA1 Message Date
Miles Malerba
afd2fd8681 refactor(compiler): ensure correct ordering of properties and attributes (#50805)
Ensures that all property and attribute ops are ordered consistently
regardless of the order they appear in the template. This ensures
correct precedence (e.g. `[style.color]="'#000'"` awlays wins out over
`[style]="{color: '#fff'}"`)

PR Close #50805
2023-07-17 17:03:57 +00:00
Miles Malerba
03e6dc3f28 refactor(compiler): normalize style prop binding names (#50805)
Normalizes style property names in bindings by converting them to
kebab-case and stripping off `!important`

PR Close #50805
2023-07-17 17:03:57 +00:00
Miles Malerba
c27d6b6b37 build: enable newly passing style tests for the template compiler (#50805)
Enables style tests that are now passing in the template compiler thanks
to recent fixes

PR Close #50805
2023-07-17 17:03:57 +00:00
Miles Malerba
2f7072dc3f refactor(compiler): add support for class property bindings (#50805)
Adds support for bindings of the form `[class.some-class]="isActive"`

PR Close #50805
2023-07-17 17:03:57 +00:00
Miles Malerba
021025964a refactor(compiler): add support for class map interpolation bindings (#50805)
Adds support for bindings of the form `class="static {{dynamic}}"`

PR Close #50805
2023-07-17 17:03:57 +00:00
Miles Malerba
7e5e37af36 refactor(compiler): add support for class map bindings (#50805)
Adds support for bindings of the form `[class]="classActiveMap"`

PR Close #50805
2023-07-17 17:03:57 +00:00
Joey Perrott
743be79749 ci: migrate windows job to GHA (#51010)
Migrate windows job to use Github Actions

PR Close #51010
2023-07-17 14:51:36 +00:00
Charles Lyding
5bd530ab32 refactor(compiler-cli): add internal compiler option to control NgModule selector scope emit (#51007)
An internal compiler option named `supportJitMode` is now available for use by the Angular CLI.
This option currently controls the emit of NgModule selector scope information. This emitted
information is only needed in AOT mode when an application also uses JIT. However, AOT mode
combined with JIT mode is not currently supported nor will work in the Angular CLI. With
the Angular CLI, JIT mode is only supported if the entire application is built in JIT mode.
Without this option, the CLI needs to manually perform a code transform to remove the information
and also replicate TypeScript's import eliding. This is can be a complicated operation and must
be continually kept up to date with any changes to both the Angular compiler and TypeScript.
The introduction of this new option alleviates these concerns while also removing several build
time actions that would otherwise need to be performed on every application build.

PR Close #51007
2023-07-13 09:32:11 -07:00
Dylan Hunn
875851776c refactor(compiler): Generate attribute and attributeInterpolate instructions in template pipeline (#50818)
This commit adds the ability to generate attribute instructions as a result of property bindings such as `[attr.foo]='bar'` or `attr.foo='{{bar}}'`. "Singleton" interpolations, such as the previous example, will also be transformed into a simple `attribute` instruction.

PR Close #50818
2023-07-10 07:17:18 -07:00
Payam Valadkhan
5724dbc82d test(compiler-cli): add compliance tests for NgModule only scenarios in local mode (#50577)
Reused the existing compliance tests for full compilation.

PR Close #50577
2023-06-30 11:38:36 -07:00
Payam Valadkhan
c1d46b8c08 refactor(compiler-cli): add local option to compliance test infra (#50577)
The option 'local compile' is added for the test cases, and the locally compiled file for an input `abc.ts` is compared by default with the file `abc.local.js`. This allows to use the same input `abc.ts` for both full compilation (compared with `abc.js`) and local compilation (compared with `abc.local.js`). An example is provided in the next commit when compliance tests are added for the NgModule local compilation.

PR Close #50577
2023-06-30 11:38:35 -07:00
Dylan Hunn
29bf476bfe refactor(compiler): Generate temporary variable assignments when function calls appear in a safe-access expression. (#50688)
The expression `a()?.b` should expand into `(tmp = a()) === null ? null : tmp.b`, in order to avoid calling the function `a()` twice.

This commit modifies the null-safe-expansion algorithm to emit temporary assignments, and provides the reification code to actually generate the declarations, assignments, and reads.

Note also that, with our bottom-up algorithm, there are some tricky cases when a function call exists inside an indexed access, such as `f1()?.[f2()?.a]?.b`. We add some special logic to avoid generating a double-assignment to the temporary storing the result of `f2()`.

Finally, there are opportunities to reuse the same temporary in expressions like `a?.[f()]?.[f()]`. We save this for the next commit.

PR Close #50688
2023-06-29 12:54:23 -07:00
Paul Gschwendtner
e699f1a75d build: allow for compliance specs only using template pipeline (#50835)
When writing signal compliance tests, we need to limit these to only the
template pipeline.

PR Close #50835
2023-06-26 13:36:06 -07:00
Miles Malerba
060830e936 refactor(compiler): add support for interpolation in style mappings (#50489)
Add support for interpolation in style map bindings in the template
pipeline

PR Close #50489
2023-06-26 13:09:25 -07:00
Miles Malerba
3c1feedff8 refactor(compiler): add support for interpolation in style properties (#50489)
Add support for interpolation in style property bindings in the template
pipeline

PR Close #50489
2023-06-26 13:09:24 -07:00
Miles Malerba
3627e4c4e7 refactor(compiler): add support for empty bindings (#50489)
Add support for empty bindings in the template pipeline

PR Close #50489
2023-06-26 13:09:24 -07:00
Miles Malerba
ebe10dd68f refactor(compiler): add support style property units (#50489)
Add support for specifying units in style property bindings in the
template pipeline

PR Close #50489
2023-06-26 13:09:24 -07:00
Miles Malerba
b289332f2c refactor(compiler): add support for style map bindings (#50489)
Add support for style map bindings in the template pipeline

PR Close #50489
2023-06-26 13:09:24 -07:00
Miles Malerba
1b038945ee refactor(compiler): add support for style property bindings (#50489)
Add support for style property bindings in the template pipeline

PR Close #50489
2023-06-26 13:09:24 -07:00
Charles Lyding
47cc56858f refactor(compiler-cli): add internal compiler option to control class metadata emit (#50604)
An internal compiler option named `supportTestBed` is now available for use by the
Angular CLI. This option currently controls the extraction and emit of Angular class
metadata. This emitted information is only needed in AOT mode when using certain
TestBed APIs. However, AOT mode is currently not available for unit testing within
the Angular CLI. As a result, the metadata is not used within CLI generation applications
and in particular production applications. Without this option, the CLI needs to
manually perform a code transform to remove the metadata and also replicate TypeScript's
import eliding. This is can be a complicated operation and must be continually kept
up to date with any changes to both the Angular compiler and TypeScript. The introduction
of this new option alleviates these concerns.

PR Close #50604
2023-06-20 13:01:48 -07:00
Paul Gschwendtner
cec5cd6eb5 test: mark ngtsc test target as flaky (#50718)
A larger investigation on why this is flaky is needed. Currently the
test is flaky with around 77% sucess rate and negatively impacts team
productivity. Subjectively, as reported by team members this it's much
more flaky than a success rate of 77%.

PR Close #50718
2023-06-15 15:34:43 +02:00
Paul Gschwendtner
12bad6576d fix(compiler-cli): libraries compiled with v16.1+ breaking with Angular framework v16.0.x (#50714)
If a library is compiling with Angular v16.1.0, the library will break
for users that are still on Angular v16.0.x. This happens because the
`DirectiveDeclaration` or `ComponentDeclaration` types are not expecting
an extra field for `signals` metadata. This field was only added to the
generic types in `16.1.0`- so compilations fail with errors like this:

```
Error: node_modules/@angular/material/icon/index.d.ts:204:18 -
  error TS2707: Generic type 'ɵɵComponentDeclaration' requires between 7 and 9 type arguments.
```

To fix this, we quickly roll back the code for inserting this metadata
field. That way, libraries remain compatible with all v16.x framework
versions.

We continue to include the `signals` metadata if `signals: true` is set.
This is not public API anyway right now- so cannot happen- but imagine
we expose some signal APIs in e.g. 16.2.x, then we'd need this metadata
and can reasonably expect signal-component library users to use a more
recent framework core version.

PR Close #50714
2023-06-14 16:27:59 +02:00
Dylan Hunn
88962b72a9 refactor(compiler): Support safe property reads and keyed reads. (#50594)
Angular's null-safe access operators differ from Javascript's built-in semantics, in that they short-circuit to `null` instead of `undefined`. This necessitates providing a custom transformation, instead of relying on Typescript or Javascript itseld.

The old TemplateDefinitionBuilder uses a top-down approach based on the Visitor pattern, in which it recursively extracts the left-most safe access, and hoists it to a null check at the top. See `expression_converter.ts` for details.

In this commit, we replace that approach with a new bottom-up algorithm, as part of the template pipeline. This requires an intermediate expression type to represent the not-yet-expanded ternary operators, and is split into its own pass.

Null-safe function calls are not yet implemented, since they will rely on a future temporary variable allocation pass.

Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>

PR Close #50594
2023-06-13 18:59:43 +02:00
Miles Malerba
15ab146e6c refactor(compiler): improve handling of bindings and attributes (#50664)
Refactor attribute and property binding ingestion and add an attribute extraction phase

Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>
Co-authored-by: Dylan Hunn <dylhunn@users.noreply.github.com>

Only add the value to the ElementAttributes map for style and attribute kinds

Other kinds should not have their value represented in the consts array

Add missing attribute ingesiton for templates

Unify how template and element bindings are ingested

This resolves the issue of missing listener attributes on templates. In
order to avoid emitting extraneous instructions, listener ops on
templates are stripped in the attribute extraction phase instead.

Handle different binding types separately in ingest

Cleanup code and comments

Disable test that fails on new explicit error.

Previously the test was passing because ingestPropertyBinding treated
attribute bindings as normal bindings which happened to be ok for the
particular test. Now there's an explicit error that attrbiute bindings
aren't yet handled which causes the test to fail

Address feeback

PR Close #50664
2023-06-13 18:34:58 +02:00
Miles Malerba
9429f96f62 test(compiler): Prevent back-sliding on already passing template pipeline tests (#50582)
Add a flag to disable specific tests when testing the template pipeline

Mark the currently failing tests

Add the template pipeline tests to CI

Update package.json

Co-authored-by: Paul Gschwendtner <paulgschwendtner@gmail.com>

PR Close #50582
2023-06-12 18:25:41 +02:00
aanchal
24c8e4e753 docs: removed duplicated words (#50648)
PR Close #50648
2023-06-12 11:43:42 +02:00
Kristiyan Kostadinov
cf15c290f0 build: update to TypeScript 5.1 final (#50548)
Bumps us up to the final version of TypeScript 5.1 which dropped overnight.

PR Close #50548
2023-06-02 14:06:46 -07:00
Kristiyan Kostadinov
68017d4e75 feat(core): add ability to transform input values (#50420)
According to the HTML specification most attributes are defined as strings, however some can be interpreted as different types like booleans or numbers. [In the HTML standard](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes), boolean attributes are considered `true` if they are present on a DOM node and `false` if they are omitted. Common examples of boolean attributes are `disabled` on interactive elements like `<button>` or `checked` on `<input type="checkbox">`. Another example of an attribute that is defined as a string, but interpreted as a different type is the `value` attribute of `<input type="number">` which logs a warning and ignores the value if it can't be parsed as a number.

Historically, authoring Angular inputs that match the native behavior in a type-safe way has been difficult for developers, because Angular interprets all static attributes as strings. While some recent TypeScript versions made this easier by allowing setters and getters to have different types, supporting this pattern still requires a lot of boilerplate and additional properties to be declared. For example, currently developers have to write something like this to have a `disabled` input that behaves like the native one:

```typescript
import {Directive, Input} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input()
  get disabled() {
    return this._disabled;
  }
  set disabled(value: any) {
    this._disabled = typeof value === 'boolean' ? value : (value != null && value !== 'false');
  }
  private _disabled = false;
}
```

This feature aims to address the issue by introducing a `transform` property on inputs. If an input has a `transform` function, any values set through the template will be passed through the function before being assigned to the directive instance. The example from above can be rewritten to the following:

```typescript
import {Directive, Input, booleanAttribute} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input({transform: booleanAttribute}) disabled: boolean = false;
}
```

These changes also add the `booleanAttribute` and `numberAttribute` utilities to `@angular/core` since they're common enough to be useful for most projects.

Fixes #8968.
Fixes #14761.

PR Close #50420
2023-05-30 13:01:13 -07:00
BrianDGLS
2d411430e3 refactor(router): run spell check on router package (#50445)
Fix typos in router package.

PR Close #50445
2023-05-24 13:56:56 +00:00
Kristiyan Kostadinov
f6da091228 refactor(compiler): introduce compiler infrastructure for input transforms (#50225)
Adds the necessary compiler changes to support input transform functions. The compiler output has changed in the following ways:

### Directive handler
The directive handler now extracts a reference to the input transform function and it resolves the type of its first parameter. It also asserts that the type can be referenced in the compiled output and that it doesn't clash with any pre-existing `ngAcceptInputType_` members.

### .d.ts
In the generated declaration files the compiler now inserts an `ngAcceptInputType_` member for each input with a `transform` function. The member's type corresponds to the type of the first parameter of the function, e.g.

```typescript
// foo.directive.ts
@Directive()
export class Foo {
  @Input({transform: (incomingValue: string) => parseInt(incomingValue)}) value: number;
}

// foo.directive.d.ts
export class Foo {
  value: number;
  static ngAcceptInputType_value: string;
}
```

### Type check block
If an input has `transform` function, the TCB will use the type of its first parameter for the setter type. This uses the same infrastructure as the `ngAcceptInputType_` members.

### Directive declaration
The generated runtime directive declaration call now includes the `transform` function in the `inputs` map, if the input is being transformed. The function will be picked up by the runtime in the next commit to do the actual transformation.

```typescript
// foo.directive.ts
@Directive()
export class Foo {
  @Input({transform: (incomingValue: string) => parseInt(incomingValue)}) value: number;
}

// foo.directive.js
export class Foo {
  ɵdir = ɵɵdefineDirective({
    inputs: {
      value: ['value', 'value', incomingValue => parseInt(incomingValue)]
    }
  });
}
```

PR Close #50225
2023-05-22 14:48:02 +00:00
Kristiyan Kostadinov
8b44ba3170 fix(core): host directives incorrectly validating aliased bindings (#50364)
Fixes that the host directives feature was incorrectly throwing the conflicting alias error when an aliased binding was being exposed under the same alias.

Fixes #48951.

PR Close #50364
2023-05-19 15:09:48 +00:00
Angular Robot
84a2e7db55 build: lock file maintenance (#49914)
See associated pull request for more information.

PR Close #49914
2023-05-09 14:38:45 -07:00
Andrew Scott
5214df4958 refactor(compiler-cli): Add signals to internal directive metadata (#49981)
This commit adds the `signals: boolean` property to the internal
directive/component metadata. This does not add it to the public API
yet, as the feature has no internal support other than compiler
detection.

PR Close #49981
2023-04-25 15:39:18 -07:00
Alex Rickabaugh
78c76cecf9 perf(compiler-cli): optimize NgModule emit for standalone components (#49837)
NgModules which import standalone components currently list those components
in their injector definitions, because we assume that any standalone
component may export providers from its own imports.

This commit adds an optimization for that emit, which attempts to statically
analyze the NgModule imports and determine which standalone components, if
any are present, do not export providers and thus can be omitted.

This analysis is imperfect, because some imported components may be declared
outside of the current compilation, or transitively import types which are
declared outside the compilation. These types are therefore _assumed_ to
carry providers and so the optimization isn't applied to them.

PR Close #49837
2023-04-17 14:51:58 +00:00
Andrew Scott
e949548561 fix(compiler): Produce diagnositc if directive used in host binding is not exported (#49527)
The compiler currently does not check to make sure that directives in
the host bindings are exported. These directives are part of the public
API of the component so they do have to be.

PR Close #49527
2023-04-11 14:02:51 -07:00
Andrew Scott
8a75a8ad26 fix(compiler-cli): Catch FatalDiagnosticError during template type checking (#49527)
This commit updates the type checking operation to catch
`FatalDiagnosticError` and surface them as diagnostics rather than
crashing.

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

PR Close #49527
2023-04-11 14:02:51 -07:00
JoostK
2d6e6a1510 refactor(compiler-cli): update comments to account for ngcc removal (#49136)
This commit updates comments to account for the removal of ngcc.

PR Close #49136
2023-04-03 19:20:01 -07:00
JoostK
e5a30d92d2 refactor(compiler-cli): update compilation error message to not mention ngcc (#49136)
No longer refer to an ngcc incompatibility now that ngcc has been removed.

PR Close #49136
2023-04-03 19:20:00 -07:00
Kristiyan Kostadinov
8f539c11f4 feat(compiler): add support for compile-time required inputs (#49468)
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.

Fixes #37706.

PR Close #49468
2023-03-20 13:10:30 +01:00
Andrew Scott
8d99ad0a39 Revert "feat(compiler): add support for compile-time required inputs (#49453)" (#49467)
This reverts commit 13dd614cd1.

This breaks a g3 Typescript compilation tests where diagnostics are
expected for a missing input in the component.

PR Close #49467
2023-03-17 18:29:14 +01:00
Kristiyan Kostadinov
13dd614cd1 feat(compiler): add support for compile-time required inputs (#49453)
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.

Fixes #37706.

PR Close #49453
2023-03-17 11:49:17 +01:00
Alex Rickabaugh
560b226a43 Revert "feat(compiler): add support for compile-time required inputs (#49304)" (#49449)
This reverts commit 1a6ca68154.

This breaks tests in google3 which might be depending on private APIs. We
need to update these tests before we can land this PR.

PR Close #49449
2023-03-16 10:38:04 -07:00
Kristiyan Kostadinov
1a6ca68154 feat(compiler): add support for compile-time required inputs (#49304)
Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:
* Inputs are marked as required by passing an object literal with a `required: true` property to the `Input` decorator or into the `inputs` array.
* Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
* Required input diagnostics are reported through the `OutOfBandDiagnosticRecorder`, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
* Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.

Fixes #37706.

PR Close #49304
2023-03-15 16:59:24 -07:00
Paul Gschwendtner
c241f63e8d refactor(compiler-cli): remove unused class decorator downlevel code (#49351)
The decorator downlevel transform is never used for actual class
decorators because Angular class decorators rely on immediate execution
for JIT. Initially we also supported downleveling of class decorators
for View Engine library output, but libraries are shipped using partial
compilation output and are not using this transform anymore.

The transform is exclusively used for JIT processing, commonly for
test files to help ease temporal dead-zone/forward-ref issues. We can
remove the class decorator downlevel logic to remove technical debt.

PR Close #49351
2023-03-08 17:59:12 +00:00
Alan Agius
1418d1937f test(compiler): add test case for merging objects in tsconfig (#49125)
This commit adds a test case for validate that we do not deep merge objects like like 'paths' and `extendedDiagnostics`.

PR Close #49125
2023-03-06 16:57:28 +00:00
Alan Agius
1407a9aeaf feat(compiler): support multiple configuration files in extends (#49125)
TypeScript 5 support `extends` to be an array, this commit adds support to allow extending `angularCompilerOptions` from multiple config files.

See: https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#supporting-multiple-configuration-files-in-extends

PR Close #49125
2023-03-06 16:57:28 +00:00
Kristiyan Kostadinov
99d874fe3b feat(core): add support for TypeScript 5.0 (#49126)
Updates the project to support TypeScript 5.0 and to resolve any errors that came up as a result of the update.

PR Close #49126
2023-02-28 08:24:47 -08:00
Paul Gschwendtner
b6c6dfd278 fix(compiler-cli): do not persist component analysis if template/styles are missing (#49184)
Consider the following scenario:

1. A TS file with a component and templateUrl exists
2. The template file does not exist.
3. First build: ngtsc will properly report the error, via a FatalDiagnosticError
4. The template file is now created
5. Second build: ngtsc still reports the same errror.

ngtsc persists the analysis data of the component and never invalidates
it when the template/style file becomes available later.

This breaks incremental builds and potentially common workflows
where resource files are added later after the TS file is created. This
did surface as an issue in the Angular CLI yet because Webpack requires
users to re-start the process when a new file is added. With ESBuild
this will change and this also breaks incremental builds with
Bazel/Blaze workers.

To fix this, we have a few options:

* Invalidate the analysis when e.g. the template file is missing. Never
  caching it means that it will be re-analyzed on every build iteration.
* Add the resource dependency to ngtsc's incremental file graph. ngtsc
  will then know via `host.getModifiedResources` when the file becomes
  available- and fresh analysis of component would occur.

The first approach is straightforward to implement and was chosen here.
The second approach would allow ngtsc to re-use more of the analysis
when we know that e.g. the template file still not there, but it
increases complexity unnecessarily because there is no **single**
obvious resource path for e.g. a `templateUrl`. The URL is attempted
to be resolved using multiple strategies, such as TS program root dirs,
or there is support for a custom resolution through
`host.resourceNameToFileName`.

It would be possible to determine some candidate paths and add them to
the dependency tracker, but it seems incomplete given possible external
resolvers like `resourceNameToFileName` and also would likely not have
a sufficient-enough impact given that a broken component decorator is
not expected to remain for too long between N incremental build
iterations.

PR Close #49184
2023-02-24 08:24:07 -08:00
Andrew Kushnir
83a6e203e3 refactor(compiler): drop obsolete NgFactory and NgSummary config options (#48268)
The options to generate NgFactory and NgSummary files were added to Ivy for backwards compatibility with ViewEngine. Since ViewEngine was deprecated and removed, the NgFactory and NgSummary files are no longer used as well.

This commit drops obsolete options to generate NgFactory and NgSummary files. Also, the logic that generates those files is also removed.

PR Close #48268
2023-02-21 13:03:59 -08:00
Kristiyan Kostadinov
d0145033bd fix(language-service): generate forwardRef for same file imports (#48898)
Adds some logic that will generate a `forwardRef` if necessary when automatically fixing an import.

PR Close #48898
2023-02-02 13:40:17 -08:00