Now that `@angular/localize` can interpret multiple legacy message ids in the
metablock of a `$localize` tagged template string, this commit adds those
ids to each i18n message extracted from component templates, but only if
the `enableI18nLegacyMessageIdFormat` is not `false`.
PR Close#34135
When creating synthesized tagged template literals, one must provide both
the "cooked" text and the "raw" (unparsed) text. Previously there were no
good APIs for creating the AST nodes with raw text for such literals.
Recently the APIs were improved to support this, and they do an extra
check to ensure that the raw text parses to be equal to the cooked text.
It turns out there is a bug in this check -
see https://github.com/microsoft/TypeScript/issues/35374.
This commit works around the bug by synthesizing a "head" node and morphing
it by changing its `kind` into the required node type.
// FW-1747
PR Close#34065
Since i18n messages are mapped to `$localize` tagged template strings,
the "raw" version must be properly escaped. Otherwise TS will throw an
error such as:
```
Error: Debug Failure. False expression: Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'.
```
This commit ensures that we properly escape these raw strings before creating
TS AST nodes from them.
PR Close#33820
This commit changes the Angular compiler (ivy-only) to generate `$localize`
tagged strings for component templates that use `i18n` attributes.
BREAKING CHANGE
Since `$localize` is a global function, it must be included in any applications
that use i18n. This is achieved by importing the `@angular/localize` package
into an appropriate bundle, where it will be executed before the renderer
needs to call `$localize`. For CLI based projects, this is best done in
the `polyfills.ts` file.
```ts
import '@angular/localize';
```
For non-CLI applications this could be added as a script to the index.html
file or another suitable script file.
PR Close#31609
To improve cross platform support, all file access (and path manipulation)
is now done through a well known interface (`FileSystem`).
For testing a number of `MockFileSystem` implementations are provided.
These provide an in-memory file-system which emulates operating systems
like OS/X, Unix and Windows.
The current file system is always available via the static method,
`FileSystem.getFileSystem()`. This is also used by a number of static
methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass
`FileSystem` objects around all the time. The result of this is that one
must be careful to ensure that the file-system has been initialized before
using any of these static methods. To prevent this happening accidentally
the current file system always starts out as an instance of `InvalidFileSystem`,
which will throw an error if any of its methods are called.
You can set the current file-system by calling `FileSystem.setFileSystem()`.
During testing you can call the helper function `initMockFileSystem(os)`
which takes a string name of the OS to emulate, and will also monkey-patch
aspects of the TypeScript library to ensure that TS is also using the
current file-system.
Finally there is the `NgtscCompilerHost` to be used for any TypeScript
compilation, which uses a given file-system.
All tests that interact with the file-system should be tested against each
of the mock file-systems. A series of helpers have been provided to support
such tests:
* `runInEachFileSystem()` - wrap your tests in this helper to run all the
wrapped tests in each of the mock file-systems.
* `addTestFilesToFileSystem()` - use this to add files and their contents
to the mock file system for testing.
* `loadTestFilesFromDisk()` - use this to load a mirror image of files on
disk into the in-memory mock file-system.
* `loadFakeCore()` - use this to load a fake version of `@angular/core`
into the mock file-system.
All ngcc and ngtsc source and tests now use this virtual file-system setup.
PR Close#30921
Currently the `@angular/compiler-cli` compliance tests sometimes do
not throw an exception if the expected output does not match the
generated JavaScript output. This can happen for the following cases:
1. Expected code includes character that is not part of known alphabet
(e.g. `Δ` is still used in a new compliance test after rebasing a PR)
2. Expected code asserts that a string literal matches a string with
escaped quotes. e.g. expects `const $var$ = "\"quoted\"";`)
PR Close#30597
There is an encoding issue with using delta `Δ`, where the browser will attempt to detect the file encoding if the character set is not explicitly declared on a `<script/>` tag, and Chrome will find the `Δ` character and decide it is window-1252 encoding, which misinterprets the `Δ` character to be some other character that is not a valid JS identifier character
So back to the frog eyes we go.
```
__
/ɵɵ\
( -- ) - I am ineffable. I am forever.
_/ \_
/ \ / \
== == ==
```
PR Close#30546
before:
```
Expected to find features 'import * as i0 from "@angular/core";
import { Directive, Input } from '@angular/core';
```
after:
```
Failed to find "template" after "...Component_Factory() { return new
MyComponent(); }," in:
'import * as i0 from "@angular/core";
import { Directive, Input } from '@angular/core';```
```
PR Close#25291
This commit moves the compiler compliance tests into compiler-cli,
and uses ngtsc to run them instead of the custom compilation
pipeline used before. Testing against ngtsc allows for validation
of the real compiler output.
This commit also fixes a few small issues that prevented the tests
from passing.
PR Close#24862