This commit extracts the patching operation that adds `fileNameToModuleName`
to the Angular compiler's `ts.CompilerHost` into a separate function, so
that it can be invoked in other compilation flows besides the one outlined
in `ngc-wrapped`. This is primarily needed for the xi18n operation in g3.
PR Close#42974
This commit is part of a larger scale change to eliminate unnecessary
escapes in string literals, in advance of enabling stricter checks in
`ts_library` rules in g3.
PR Close#42990
Add a `makeTemplateDiagnostic` wrapper in the `TemplateTypeChecker`. This requiers less parameters to create template diagnostics, since the `TemplateTypeChecker` can get the templateId and mapping from it's scope with the `ts.ClassDeclartion`. The `TemplateTypeChecker` is often used to determine if a diagnostic should be produced, so it makes sense to have a function in it that helps create them.
Refs #42966
PR Close#42937
The compiler keeps track of how a declaration has been referenced
using absolute module imports and from which path the absolute module
should be resolved from. There was a bug in how the .d.ts metadata
extraction would incorrectly use the .d.ts file itself as resolution
context for symbols that had been imported using a relative module
specifier. This could result in module resolution failures.
For example, when extracting NgModule metadata from
`/node_modules/lib/index.d.ts` that looks like
```
import {LibDirective} from './dir';
@NgModule({
declarations: [LibDirective],
exports: [LibDirective],
})
export class LibModule {}
```
and `/app.module.ts` that contains
```
import {LibModule} from 'lib';
@NgModule({
imports: [LibModule],
})
export class AppModule {}
```
then `AppModule` would have recorded a reference to `LibModule` using
the `'lib'` module specifier. When extracting the NgModule metadata from
the `/node_modules/lib/index.d.ts` file the relative import into `./dir`
should also be assumed to be importable from `'lib'` (according to APF
where symbols need to be exported from a single entry-point)
so the reference to `LibDirective` should have `'lib'` as absolute
module specifier, but it would incorrectly have
`/node_modules/lib/index.d.ts` as resolution context path. The latter is
incorrect as `'lib'` needs to be resolved from `/app.module.ts` and not
from within the library itself.
Fixes#42810
PR Close#42879
For now it's not possible to provide custom route reuse strategy via DI
for `RouterTestingModule`, only imperative instantiation. These changes
makes it possible to provide custom route reuse strategy via DI.
PR Close#42434
When `canceledNavigationResolution='computed'`, the `Router` needs to
handle the cases where errors are thrown. Previously, the logic was not
updated and would simply do a `replaceState` rather than determining
where in the history we should move to restore the page/url from before
the failed navigation.
PR Close#42933
Without the `import {Event} from '@angular/router';`, the filter will
not work because the type is understood as the native `Event`.
Fixes#42920
PR Close#42935
Several new functionalities are possible with this change: the most requested is that callers can now check whether a control has a required validator. Other uses include incrementally changing the validators set without doing an expensive operation to reset all validators.
Closes#13461.
PR Close#42838
In an incremental rebuild, the compiler attempts to reuse as much
analysis data from a prior compilation as possible to avoid doing the
analysis work again. For source files without Angular behavior however,
no analysis data would be recorded such that the source file had to be
reanalyzed each rebuild, even if it has not changed.
This commit avoids the analysis of such source files by registering
these files as not containing any Angular behavior; allowing subsequent
rebuilds to avoid the analysis work.
PR Close#42562
If the validator is bound to be `null` then no validation occurs and
attribute is not added to DOM.
For every validator type different PR will be raised as discussed in
https://github.com/angular/angular/pull/42378.
Closes#42267.
PR Close#42565
Since `ErrorHandler#handleError()` expects an argument of type `any` it
should be able to handle values such as `null` and `undefined`.
Previously, it failed to handle these values, because it was trying to
access properties on them.
This commit fixes it by ensuring no properties are accessed on `null` or
`undefined` values.
NOTE: This is part of fully addressing #28106.
Fixes#21252
PR Close#42881
The static interpreter assumed that a foreign function expression would
have to be imported from the absolute module specifier that was used for
the foreign function itself. This assumption does not hold for the
`forwardRef` foreign function resolver, as that extracts the resolved
expression from the function's argument, which is not behind the
absolute module import of the `forwardRef` function.
The prior behavior has worked for the typical usage of `forwardRef`,
when it is contained within the same source file as where the static
evaluation started. In that case, the resulting reference would
incorrectly have an absolute module guess of `@angular/core`, but the
local identifier emit strategy was capable of emitting the reference
without generating an import using the absolute module guess.
In the scenario where the static interpreter would first have to follow
a reference to a different source that contained the `forwardRef` would
the compilation fail. In that case, there is no local identifier
available such that the absolute module emitter would try to locate the
imported symbol from `@angular/core`. which fails as the symbol is not
exported from there.
This commit fixes the issue by checking whether a foreign expression
occurs in the same source file as the call expression. If it does, then
the absolute module specifier that was used to resolve the call
expression is ignored.
Fixes#42865
PR Close#42887
When a directive provides a DI token using a factory function and
interacting with a standalone injector from within that factory, the
standalone injector should not have access to either the directive
injector nor the NgModule injector; only the standalone injector should
be used.
This commit ensures that a standalone injector never reaches into the
directive-level injection context while resolving DI tokens.
Fixes#42651
PR Close#42886
the final styles created in buildStyles lack normalization, meaning that pixel values remain as numbers (without "px") and so such properties fail to be correctly set/applied
Example: "width: 300" is applies as "width": "300" (and thus ignored) instead of the correct "width": "300px"
PR Close#42763
fix the typo "mean't" in the transition_animation_engine spec file
to "meant" (the typo is simply in a code comment so the change
does not have any impact)
PR Close#42763
With the refactoring from a Gulp task to a Bazel too, we tried switching
away from the hard-coded list of locales and aliases for the Closure
Locale file generation. After multiple attempts of landing this, it
turned out that Closure Compiler/Closure Library relies on locale
identifiers CLDR does not capture within it's `availableLocales.json`
or `aliases.json` data.
Closure Library does not use any unknown locale identifiers here. The
locale identifiers can be resolved within CLDR using the bundle lookup
algorithm that is specified as part of CLDR; instead the problem is that
the locale identifiers do not follow any reasonable pattern and
therefore it's extremely difficult to generate them automatically (it's
almost like we'd need to build up _all_ possible combinations). Instead
of doing that, we just use the hard-coded locales and aliases from the
old Closure Locale generation script.
PR Close#42230
Within Google, closure compiler is used for dealing with translations.
We generate a closure-compatible locale file that allows for
registration within Angular, so that Closure i18n works well together
with Angular applications. Closure compiler does not limit its
locales to BCP47-canonical locale identifiers. This commit updates
the generation logic so that we also support deprecated (but aliased)
locale identifiers, or other aliases which are likely used within
Closure. We use CLDR's alias supplemental data for this. It instructs
us to alias `iw` to `he` for example. `iw` is still supported in Closure.
Note that we do not manually extract all locales supported in Closure;
instead we only support the CLDR canonical locales (as done before) +
common aliases that CLDR provides data for. We are not aware of other
locale aliases within Closure that wouldn't be part of the CLDR aliases.
If there would be, then Angular/Closure would fail accordingly.
PR Close#42230
In the past, the closure file has been generated so that all individual
locale files were imported individually. This resulted in a huge
slow-down in g3 due to the large amount of imports.
With 90bd984ff7 this changed so that we
inline the locale data for the g3 closure locale file. Also the file
only contained data for locales being supported by Closure. For this a
list of locales has been extracted from Closure Compiler, as well as a
list of locale aliases.
This logic is prone to CLDR version updates, and also broke as part of
the Gulp -> Bazel migration where this logic has been slightly modified
but caused issues in G3. e.g. a locale `zh-Hant` was requested in g3,
but the locale data had the name of the alias locale that provided the
data at index zero (which represents the locale name). Note that the
locale names at index zero always could differentiate from the requested
`goog.LOCALE` due to the aliasing logic. This just didn't come up before.
We simplify this logic by generating a `goog.LOCALE` case for all
locales CLDR provides data for. We don't need to bother about aliasing
because with the refactorings to the CLDR generation tool, all locales
are built (which also captures the aliases), and we can generate the locale
file on the fly (which has not been done before).
PR Close#42230
The CLDR extraction tool has been reworked to run as part of Bazel.
This adds a initial readme explaining what the tool generates. It's
far from a detailed description but it can serve as foundation for more
detailed explanations.
PR Close#42230
Introduces a few Starlark macros for running the new Bazel
CLDR generation tool. Wires up the new tool so that locales
are generated properly. Also updates the existing
`closure-locale` file to match the new output generated by the Bazel tool.
This commit also re-adds a few locale files that aren't
generated by CLDR 37, but have been accidentally left in
the repository as the Gulp script never removed old locales
from previous CLDR versions. This problem is solved with the
Bazel generation of locale files, but for now we re-add these
old CLDR 33 locale files to not break developers relying on these
(even though the locale data indicies are incorrect; but there might
be users accessing the data directly)
PR Close#42230
Converts the CLDR locale extraction script to a Bazel tool.
This allows us to generate locale files within Bazel, so that
locales don't need to live as sources within the repo. Also
it allows us to get rid of the legacy Gulp tooling.
The migration of the Gulp script to a Bazel tool involved the
following things:
1. Basic conversion of the `extract.js` script to TypeScript.
This mostly was about adding explicit types. e.g. adding `locale:
string` or `localeData: CldrStatic`.
2. Split-up into separate files. Instead of keeping the large
`extract.js` file, the tool has been split into separate files.
The logic remains the same, just that code is more readable and
maintainable.
3. Introduction of a new `index.ts` file that is the entry-point
for the Bazel tool. Previously the Gulp tool just generated
all locale files, the default locale and base currency files
at once. The new entry-point accepts a mode to be passed as
first process argument. based on that argument, either locales
are generated into a specified directory, or the default locale,
base currencies or closure file is generated.
This allows us to generate files with a Bazel genrule where
we simply run the tool and specify the outputs. Note: It's
necessary to have multiple modes because files live in separate
locations. e.g. the default locale in `@angular/core`, but the
rest in `@angular/common`.
4. Removal of the `cldr-data-downloader` and custom CLDR resolution
logic. Within Bazel we cannot run a downloader using network.
We switch this to something more Bazel idiomatic with better
caching. For this a new repository rule is introduced that
downloads the CLDR JSON repository and extracts it. Within
that rule we determine the supported locales so that they
can be used to pre-declare outputs (for the locales) within
Bazel analysis phase. This allows us to add the generated locale
files to a `ts_library` (which we want to have for better testing,
and consistent JS transpilation).
Note that the removal of `cldr-data-downloader` also requires us to
add logic for detecting locales without data. The CLDR data
downloader overwrote the `availableLocales.json` file with a file
that only lists locales that CLDR provides data for. We use the
official `availableLocales` file CLDR provides, but filter out
locales for which no data is available. This is needed until we
update to CLDR 39 where data is available for all such locales
listed in `availableLocales.json`.
PR Close#42230
This is a pre-refactor commit allowing us to move
the CLDR locale generation to Bazel where files would
no longer be checked-in, except for the `closure-locale`
file that is synced into Google3.
PR Close#42230
If a decorator or partial declaration has not been AOT compiled, then
the compiler is needed at runtime to be able to JIT compile the code.
However, it may occur that the compiler is not available, if it has not
been loaded into the application. The error that was reported in this
case did not provide insight into which class requested compilation, nor
did it differentiate between decorators vs. partial declarations.
This commit expands the error logging to provide better insight into the
class that initiated JIT compilation and offers a specialized error
message for partial declarations. This should help a developer better
understand why the error occurs and what can be done to resolve it.
Closes#40609
PR Close#42693
For the compilation of a component, the compiler verifies that the
imports it needs to generate to reference the used directives and pipes
would not create an import cycle in the program. This requires visiting
the transitive import graphs of all directive/pipe usage in search of
the component file. The observation can be made that all directive/pipe
usages can leverage the exploration work in search of the component
file, thereby allowing sub-graphs of the import graph to be only visited
once instead of repeatedly per usage. Additionally, the transitive
imports of a file are no longer collected into a set to reduce memory
pressure.
PR Close#41271
When using `TestBed.overrideComponent`, the overridden component would
incorrectly lose access to its NgModule's declaration scope if the
NgModule had been imported into the testing NgModule as a
`ModuleWithProviders`, e.g. using a `forRoot` call.
The issue occurred as the `TestBed` compiler did not consider NgModules
that had been imported as a `ModuleWithProviders` when associating
NgModules with component overrides. This caused the overridden component
to be compiled standalone, meaning that it does not have access to
its NgModule's declarations. This commit extends the logic for
traversing the NgModule graph to also consider `ModuleWithProviders`
imports.
Fixes#42734
PR Close#42817
In #41995 the type of `TrackByFunction` was changed such that the
declaration of a `trackBy` function did not cause the item type to be
widened to the `trackBy`'s item type, which may be a supertype of the
iterated type. This has introduced situations where the template type
checker is now reporting errors for cases where a `trackBy` function is
no longer assignable to `TrackByFunction`.
This commit fixes the error by also including the item type `T` in
addition to the constrained type parameter `U`, allowing TypeScript to
infer an appropriate `T`.
Fixes#42609
PR Close#42692
Previously, if only the `compareFn` changed but the data itself did not, then
the `KeyValuePipe` did not re-sort the output.
Fixes#42819
PR Close#42821
Angular inserts text either through text nodes (`document.createTextNode`) or using `textContent`, but the drawback of doing so is that HTML entities won't be decoded. In order to work around it, the compiler has some logic that maps the entities to their unicode representation which can safely be inserted. The problem is that our current mapping is arbitrarily limited which means that some entities will be mapped while others will throw an error, even though they're valid.
These changes expand the list to cover all entities that are supported by the HTML spec.
Fixes#41186.
PR Close#42818
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.
PR Close#42512