This release brings in some important fixes. In particular the 2 segment linker fix for the new rollup_bundle and the strict peerDeps requirement will be important for angular users that opt in to bazel. See https://github.com/bazelbuild/rules_nodejs/releases/tag/0.39.0 for more details.
PR Close#33426
The `localize-translate` command line tool can now accept an array of
target locales to support the case where translation files do not
contain them. Specify this array via the `--target-locales` option.
NOTE to early adopters: in order to support this, the original `-t`
option for the binary has changed from being a glob pattern to an array
of paths, which will have matching indices to any provided target-locales.
PR Close#33381
Previously the target locale of a translation file had to be extracted
from the contents of the translation file. Therefore it was an error if
the translation file did not provide a target locale.
Now an array of locales can be provided via the `translationFileLocales`
option that overrides any target locale extracted from the file.
This allows us to support translation files that do not have a target
locale specified in their contents.
// FW-1644
Fixes#33323
PR Close#33381
Currently the `missing-injectable` migration seems to add
`@Injectable()` to third-party classes in type definitions.
This not an issue in general since we do not generate broken code
by inserting a decorator into a type definition file. Though, we can
avoid adding the decorator since it won't have any effect and in
general we should not write to non source files of the compilation unit.
PR Close#33286
We should not migrate the reference from `useExisting`. This is because
developers can only use the `useExisting` value as a token. e.g.
```ts
@NgModule({
providers: [
{provide: AppRippleConfig, useValue: rippleOptions},
{provide: MAT_RIPPLE_OPTIONS, useExisting: AppRippleConfig},
]
})
export class AppModule {}
```
In the case above, nothing should be decorated with `@Injectable`. The
`AppRippleConfig` class is just used as a token for injection.
PR Close#33286
Currently the migration is unable to migrate instances where
the provider definition uses `forwardRef`. Since this is a
common pattern, we should support that from within the migration.
The solution to the problem is adding a foreign function resolver
to the `PartialEvaluator`. This basically matches the usage of
the static evaluation that is used by the ngtsc annotations.
PR Close#33286
this makes running and profiling tests much easier. Example usage:
```
yarn bazel run --define=compile=aot //packages/core/test/render3/perf:noop_change_detection
```
See README.md update for more info.
PS: I considered moving the ng_rollup bundle into the macro but I didn't want to make
too many changes in this PR. If we find running benchmarks in this way useful, we
should refactor the build file more, and move the ng_rollup_bundle targets into the
macro.
PR Close#33389
Removes `ngBaseDef` from the compiler and any runtime code that was still referring to it. In the cases where we'd previously generate a base def we now generate a definition for an abstract directive.
PR Close#33264
For abstract directives, i.e. directives without a selector, it may
happen that their constructor is called explicitly from a subclass,
hence its parameters are not required to be valid for Angular's DI
purposes. Prior to this commit however, having an abstract directive
with a constructor that has parameters that are not eligible for
Angular's DI would produce a compilation error.
A similar scenario may occur for `@Injectable`s, where an explicit
`use*` definition allows for the constructor to be irrelevant. For
example, the situation where `useFactory` is specified allows for the
constructor to be called explicitly with any value, so its constructor
parameters are not required to be valid. For `@Injectable`s this is
handled by generating a DI factory function that throws.
This commit implements the same solution for abstract directives, such
that a compilation error is avoided while still producing an error at
runtime if the type is instantiated implicitly by Angular's DI
mechanism.
Fixes#32981
PR Close#32987
Also removes `build:remote --spawn_strategy=remote` from .bazelrc. It seems that with Bazel 1.0.0 setting `--incompatible_list_based_execution_strategy_selection=false` no longer works around the issue with npm_package that it did when it was added. The error that was originally observed has returned after updating to Bazel 1.0.0:
```
ERROR: /home/circleci/ng/packages/angular_devkit/build_optimizer/BUILD:66:1: Assembling npm package packages/angular_devkit/build_optimizer/npm_package failed: No usable spawn strategy found for spawn with mnemonic Action. Your --spawn_strategy, --genrule_strategy or --strategy flags are probably too strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for migration advice
```
This commit removes both `—incompatible_list_based_execution_strategy_selection=false` as well as `build:remote --spawn_strategy=remote` which means that Bazel will do the default behavior of picking the first available strategy from the default list, which is `remote,worker,sandboxed,local`. See https://github.com/bazelbuild/bazel/issues/7480 for more details.
PR Close#33367
This commit removes HTML elements and HTML attributes from the
completions list for external template. This is because these
completions should be handled by the native HTML extension, and not
Angular.
Once we setup TextMate grammar for inline templates, we could remove the
HTML completions completely.
PR closes https://github.com/angular/vscode-ng-language-service/issues/370
PR Close#33388
The styling algorithm requires that the `RNode` has a `className`
property in order to execute the fast-path. This changes adds the
emulation of this property.
PR Close#33392
In Angular View Engine, there are two kinds of decorator inheritance:
1) both the parent and child classes have decorators
This case is supported by InheritDefinitionFeature, which merges some fields
of the definitions (such as the inputs or queries).
2) only the parent class has a decorator
If the child class is missing a decorator, the compiler effectively behaves
as if the parent class' decorator is applied to the child class as well.
This is the "undecorated child" scenario, and this commit adds a migration
to ngcc to support this pattern in Ivy.
This migration has 2 phases. First, the NgModules of the application are
scanned for classes in 'declarations' which are missing decorators, but
whose base classes do have decorators. These classes are the undecorated
children. This scan is performed recursively, so even if a declared class
has a base class that itself inherits a decorator, this case is handled.
Next, a synthetic decorator (either @Component or @Directive) is created
on the child class. This decorator copies some critical information such
as 'selector' and 'exportAs', as well as supports any decorated fields
(@Input, etc). A flag is passed to the decorator compiler which causes a
special feature `CopyDefinitionFeature` to be included on the compiled
definition. This feature copies at runtime the remaining aspects of the
parent definition which `InheritDefinitionFeature` does not handle,
completing the "full" inheritance of the child class' decorator from its
parent class.
PR Close#33362
This commit adds CopyDefinitionFeature, which supports the case where an
entire decorator (@Component or @Directive) is inherited from parent to
child.
The existing inheritance feature, InheritDefinitionFeature, supports merging
of parent and child definitions when both were originally present. This
merges things like inputs, outputs, host bindings, etc.
CopyDefinitionFeature, on the other hand, compensates for a definition that
was missing entirely on the child class, by copying fields that aren't
ordinarily inherited (like the template function itself).
This feature is intended to only be used as part of ngcc code generation.
PR Close#33362
When upgrading an Angular application to a new version using the Angular
CLI, built-in schematics are being run to update user code from
deprecated patterns to the new way of working. For libraries that have
been built for older versions of Angular however, such schematics have
not been executed which means that deprecated code patterns may still be
present, potentially resulting in incorrect behavior.
Some of the logic of schematics has been ported over to ngcc migrations,
which are automatically run on libraries. These migrations achieve the
same goal of the regular schematics, but operating on published library
sources instead of used code.
PR Close#33362
Previously, the (currently disabled) undecorated parent migration in
ngcc would produce errors when a base class could not be determined
statically or when a class extends from a class in another package. This
is not ideal, as it would cause the library to fail compilation without
a workaround, whereas those problems are not guaranteed to cause issues.
Additionally, inheritance chains were not handled. This commit reworks
the migration to address these limitations.
PR Close#33362
In ngcc's migration system, synthetic decorators can be injected into a
compilation to ensure that certain classes are compiled with Angular
logic, where the original library code did not include the necessary
decorators. Prior to this change, synthesized decorators would have a
fake AST structure as associated node and a made-up identifier. In
theory, this may introduce issues downstream:
1) a decorator's node is used for diagnostics, so it must have position
information. Having fake AST nodes without a position is therefore a
problem. Note that this is currently not a problem in practice, as
injected synthesized decorators would not produce any diagnostics.
2) the decorator's identifier should refer to an imported symbol.
Therefore, it is required that the symbol is actually imported.
Moreover, bundle formats such as UMD and CommonJS use namespaces for
imports, so a bare `ts.Identifier` would not be suitable to use as
identifier. This was also not a problem in practice, as the identifier
is only used in the `setClassMetadata` generated code, which is omitted
for synthetically injected decorators.
To remedy these potential issues, this commit makes a decorator's
identifier optional and switches its node over from a fake AST structure
to the class' name.
PR Close#33362
A class that is provided as Angular service is required to have an
`@Injectable()` decorator so that the compiler generates its injectable
definition for the runtime. Applications are automatically migrated
using the "missing-injectable" schematic, however libraries built for
older version of Angular may not yet satisfy this requirement.
This commit ports the "missing-injectable" schematic to a migration that
is ran when ngcc is processing a library. This ensures that any service
that is provided from an NgModule or Directive/Component will have an
`@Injectable()` decorator.
PR Close#33362
ngcc has an internal cache of computed decorator information for
reflected classes, which could previously be mutated by consumers of the
reflection host. With the ability to inject synthesized decorators, such
decorators would inadvertently be added into the array of decorators
that was owned by the internal cache of the reflection host, incorrectly
resulting in synthesized decorators to be considered real decorators on
a class. This commit fixes the issue by cloning the cached array before
returning it.
PR Close#33362
This patch ensures that the `[style]` and `[class]` based bindings
are directly applied to an element's style and className attributes.
This patch optimizes the algorithm so that it...
- Doesn't construct an update an instance of `StylingMapArray` for
`[style]` and `[class]` bindings
- Doesn't apply `[style]` and `[class]` based entries using
`classList` and `style` (direct attributes are used instead)
- Doesn't split or iterate over all string-based tokens in a
string value obtained from a `[class]` binding.
This patch speeds up the following cases:
- `<div [class]>` and `<div class="..." [class]>`
- `<div [style]>` and `<div style="..." [style]>`
The overall speec increase is by over 5x.
PR Close#33336
Moves to using the absolute span of an expression AST (relative to an
entire template) rather than a relative span (relative to the start
of the expression) to find an expression AST given a position in a
template.
This is part of the changes needed to support text replacement in
templates (#33091).
PR Close#33387
The template type checking abilities of the Ivy compiler are far more
advanced than the level of template type checking that was previously
done for Angular templates. Up until now, a single compiler option
called "fullTemplateTypeCheck" was available to configure the level
of template type checking. However, now that more advanced type checking
is being done, new errors may surface that were previously not reported,
in which case it may not be feasible to fix all new errors at once.
Having only a single option to disable a large number of template type
checking capabilities does not allow for incrementally addressing newly
reported types of errors. As a solution, this commit introduces some new
compiler options to be able to enable/disable certain kinds of template
type checks on a fine-grained basis.
PR Close#33365
View Engine correctly infers the type of local refs to directives or to
<ng-template>s, just not to DOM nodes. This commit splits the
checkTypeOfReferences flag into two separate halves, allowing the compiler
to align with this behavior.
PR Close#33365
For elements that have a text attribute, it may happen that the element
is matched by a directive that consumes the attribute as an input. In
that case, the template type checker will validate the correctness of
the attribute with respect to the directive's declared type of the
input, which would typically be `boolean` for the `disabled` input.
Since empty attributes are assigned the empty string at runtime, the
template type checker would report an error for this template.
This commit introduces a strictness flag to help alleviate this
particular situation, effectively ignoring text attributes that happen
to be consumed by a directive.
PR Close#33365
During the creation of an Angular program in the compiler, a check is
done to verify whether the version of TypeScript is considered
supported, producing an error if it is not. This check was missing in
the Ivy compiler, so users may have ended up running an unsupported
TypeScript version inadvertently.
Resolves FW-1643
PR Close#33377
`LFrame` stores information specifice to the current `LView` As the code
enters and leaves `LView`s we use `enterView()` and `leaveView()`
respectively to build a a stack of `LFrame`s. This allows us to easily
restore the previous `LView` instruction state.
PR Close#33178
It is messy to keep casting `CompletionEntry.kind` from
`ng.CompletionKind` to `ts.ScriptElementKind`.
Instead, create a new type `ng.CompletionEntry` that is exactly the same
as `ts.CompletionEntry`, but with the `kind` type overridden to
`ng.CompletionKind`.
This way, we only have to cast it once, and can do so in a safe manner.
PR Close#33379
Recently it was made possible to have a directive without selector,
which are referred to as abstract directives. Such directives should not
be registered in an NgModule, but can still contain decorators for
inputs, outputs, queries, etc. The information from these decorators and
the `@Directive()` decorator itself needs to be registered with the
central `MetadataRegistry` so that other areas of the compiler can
request information about a given directive, an example of which is the
template type checker that needs to know about the inputs and outputs of
directives.
Prior to this change, however, abstract directives would only register
themselves with the `MetadataRegistry` as being an abstract directive,
without all of its other metadata like inputs and outputs. This meant
that the template type checker was unable to resolve the inputs and
outputs of these abstract directives, therefore failing to check them
correctly. The typical error would be that some property does not exist
on a DOM element, whereas said property should have been bound to the
abstract directive's input.
This commit fixes the problem by always registering the metadata of a
directive or component with the `MetadataRegistry`. Tests have been
added to ensure abstract directives are handled correctly in the
template type checker, together with tests to verify the form of
abstract directives in declaration files.
Fixes#30080
PR Close#33131
During compile-time translation inlining, the `$localize.locale`
expression will now be replaced with a string literal containing the
current locale of the translations.
PR Close#33314
In the post-$localize world the current locale value is defined by setting
`$localize.locale` which is then read at runtime by Angular in the provider
for the `LOCALE_ID` token and also passed to the ivy machinery via`setLocaleId()`.
The $localize compile-time inlining tooling can replace occurrences of
`$localize.locale` with a string literal, similar to how translations
are inlined.
// FW-1639
See https://github.com/angular/angular-cli/issues/15896
PR Close#33314
Previously, we had tested that expressions parsed in a Render3 AST
had correctly-defined absolute spans (spans relative to the entire
template, not the local expression). Sometimes we use Template ASTs
rather than Render3 ASTs, and it's desirable to test for correct
expression spans in the template parser as well.
Adding these tests resolved one bug, similar to the one fixed in
fd4fed14d8, where expressions in the value
of a template attribute were not given an absolute span corresponding to
the start of the attribute name rather than the start of the attribute
value.
The diff on this commit is large, partially because it involves some
structural changes of the template parser testing layout. In particular,
the following is done:
1. Move `createMeta*`-like functions from `template_parser_spec.ts` to
be exported from a new test utility file.
2. Create an `ExpressionSourceHumanizer`, similar to the one created in
b04488d692, to allow convenient testing
of expressions' locations.
3. Create `template_parser_absolute_span_spec.ts`, testing the spans of
expressions parsed by the template parser. This is very similar to
the `r3_ast_absolute_span_spec`.
PR Close#33253
Often the types of an `@Input`'s field don't fully reflect the types of
assignable values. This can happen when an input has a getter/setter pair
where the getter always returns a narrow type, and the setter coerces a
wider value down to the narrow type.
For example, you could imagine an input of the form:
```typescript
@Input() get value(): string {
return this._value;
}
set value(v: {toString(): string}) {
this._value = v.toString();
}
```
Here, the getter always returns a `string`, but the setter accepts any value
that can be `toString()`'d, and coerces it to a string.
Unfortunately TypeScript does not actually support this syntax, and so
Angular users are forced to type their setters as narrowly as the getters,
even though at runtime the coercion works just fine.
To support these kinds of patterns (e.g. as used by Material), this commit
adds a compiler feature called "input coercion". When a binding is made to
the 'value' input of a directive like MatInput, the compiler will look for a
static field with the name ngAcceptInputType_value. If such a field is found
the type-checking expression for the input will use the static field's type
instead of the type for the @Input field,allowing for the expression of a
type conversion between the binding expression and the value being written
to the input's field.
To solve the case above, for example, MatInput might write:
```typescript
class MatInput {
// rest of the directive...
static ngAcceptInputType_value: {toString(): string};
}
```
FW-1475 #resolve
PR Close#33243
Decrease `MIN_SAMPLE_DURATION` to make it more likely that we cane fit into single time slice.
Increase `MIN_SAMPLE_COUNT_NO_IMPROVEMENT` to make it more likely to find the best
PR Close#33341
change the existing implementation from using
```
string.split(/\s+/);
```
to a char scan which performers the same thing.
The reason why `split(/\s+/)` is slow is that:
- `/\s+/` allocates new `RegExp` every time this code executes.
- `RegExp` scans are a lot more expensive because they are more powerful.
PR Close#33326
Prior to this change, a method call of a local template variable would
incorrectly be considered a call to a method on the component class.
For example, this pattern would produce an error:
```
<ng-template let-method>{{ method(1) }}</ng-template>
```
Here, the method call should be targeting the `$implicit` variable on
the template context, not the component class. This commit corrects the
behavior by first resolving methods in the template before falling back
on the component class.
Fixes#32900
PR Close#33132
In View Engine, with fullTemplateTypeCheck mode disabled, the type of any
inferred based on the entity being referenced. This is a bug, since the
goal with fullTemplateTypeCheck: false is for Ivy and VE to be aligned in
terms of type inference.
This commit adds a 'checkTypeOfReference' flag in the TypeCheckingConfig
to control this inference, and sets it to false when fullTemplateTypeCheck
is disabled.
PR Close#33261
Libraries can expose directive/component base classes that will be
used by consumer applications. Using such a base class from another
compilation unit works fine with "ngtsc", but when using "ngc", the
compiler will thrown an error saying that the base class is not
part of a NgModule. e.g.
```
Cannot determine the module for class X in Y! Add X to the NgModule to fix it.
```
This seems to be because the logic for distinguishing directives from
abstract directives is scoped to the current compilation unit within
ngc. This causes abstract directives from other compilation units to
be considered as actual directives (causing the exception).
PR Close#33347
This should be removed before for 9.0.0 rc
BREAKING CHANGE:
@angular/bazel ng_setup_workspace() is no longer needed and has been removed.
We assume you will fetch rules_nodejs in your WORKSPACE file, and no other dependencies remain here.
Simply remove any calls to this function and the corresponding load statement.
PR Close#33330
Prior to this commit, we always invoked second i18n pass (in case whitespace removal is on, which is a default), even if a given template doesn't contain i18n information. Now we store a flag (that indicates presence of i18n information in a template) during first i18n pass and use it to check whether second pass is needed.
PR Close#33284
When computing i18n messages for templates there are two passes.
This is because messages must be computed before any whitespace
is removed. Then on a second pass, the messages must be recreated
but reusing the message ids from the first pass.
Previously ICUs were losing their legacy ids that had been computed
via the first pass. This commit fixes that by keeping track of the
message from the first pass (`previousMessage`) for ICU placeholder
nodes.
// FW-1637
PR Close#33318
Previously the parameter was `id` which is ambigous because it
could be a computed value rather than a developer specified custom
value.
PR Close#33318
This commit cleans up the I18MetaVisitor code by moving all the
state of the visitor into a `context` object that gets passed along
as the nodes are being visited. This is in keeping with how visitors
are designed but also makes it easy to remove the
[definite assignment assertions](https://mariusschulz.com/blog/strict-property-initialization-in-typescript#solution-4-definite-assignment-assertion)
from the class properties.
Also, a `I18nMessageFactory` named type is exported to make it
clearer to consumers of the `createI18nMessageFactory()` function.
PR Close#33318
This is a potential fix for https://github.com/angular/vscode-ng-language-service/issues/235
suggested by @andrius-pra in
47696136e3.
Currently, CRLF line endings are converted to LFs and this causes the
diagnostics span to be off in templates that use CRLF. The line endings
must be preserved in order to maintain correct span offset. The solution
is to add an option to the Tokenizer to indicate such preservation.
PR Close#33241
This commit adapts the private NgModule re-export system (using aliasing) to
ngcc. Not all ngcc compilations are compatible with these re-exports, as
they assume a 1:1 correspondence between .js and .d.ts files. The primary
concern here is supporting them for commonjs-only packages.
PR Close#33177
This commit refactors the aliasing system to support multiple different
AliasingHost implementations, which control specific aliasing behavior
in ngtsc (see the README.md).
A new host is introduced, the `PrivateExportAliasingHost`. This solves a
longstanding problem in ngtsc regarding support for "monorepo" style private
libraries. These are libraries which are compiled separately from the main
application, and depended upon through TypeScript path mappings. Such
libraries are frequently not in the Angular Package Format and do not have
entrypoints, but rather make use of deep import style module specifiers.
This can cause issues with ngtsc's ability to import a directive given the
module specifier of its NgModule.
For example, if the application uses a directive `Foo` from such a library
`foo`, the user might write:
```typescript
import {FooModule} from 'foo/module';
```
In this case, foo/module.d.ts is path-mapped into the program. Ordinarily
the compiler would see this as an absolute module specifier, and assume that
the `Foo` directive can be imported from the same specifier. For such non-
APF libraries, this assumption fails. Really `Foo` should be imported from
the file which declares it, but there are two problems with this:
1. The compiler would have to reverse the path mapping in order to determine
a path-mapped path to the file (maybe foo/dir.d.ts).
2. There is no guarantee that the file containing the directive is path-
mapped in the program at all.
The compiler would effectively have to "guess" 'foo/dir' as a module
specifier, which may or may not be accurate depending on how the library and
path mapping are set up.
It's strongly desirable that the compiler not break its current invariant
that the module specifier given by the user for the NgModule is always the
module specifier from which directives/pipes are imported. Thus, for any
given NgModule from a particular module specifier, it must always be
possible to import any directives/pipes from the same specifier, no matter
how it's packaged.
To make this possible, when compiling a file containing an NgModule, ngtsc
will automatically add re-exports for any directives/pipes not yet exported
by the user, with a name of the form: ɵngExportɵModuleNameɵDirectiveName
This has several effects:
1. It guarantees anyone depending on the NgModule will be able to import its
directives/pipes from the same specifier.
2. It maintains a stable name for the exported symbol that is safe to depend
on from code on NPM. Effectively, this private exported name will be a
part of the package's .d.ts API, and cannot be changed in a non-breaking
fashion.
Fixes#29361
FW-1610 #resolve
PR Close#33177
Changed `setValue` documentation for throwing an error as it contained a grammar
mistake and also may have caused ambiguity around when exactly the
method would throw.
PR Close#33126
Static methods that return a type of ModuleWithProviders currently
do not have to specify a type because the generic falls back to any.
This is problematic because the type of the actual module being
returned is not present in the type information.
Since Ivy uses d.ts files exclusively for downstream packages
(rather than metadata.json files, for example), we no longer have
the type of the actual module being created.
For this reason, a generic type should be added for
ModuleWithProviders that specifies the module type. This will be
required for all users in v10, but will only be necessary for
users of Ivy in v9.
PR Close#33217
Previously, the `FileSystem` abstraction featured a `mkdir()` method. In
`NodeJSFileSystem` (the default `FileSystem` implementation used in
actual code), the method behaved similar to Node.js' `fs.mkdirSync()`
(i.e. failing if any parent directory is missing or the directory exists
already). In contrast, `MockFileSystem` (which is the basis or mock
`FileSystem` implementations used in tests) implemented `mkdir()` as an
alias to `ensureDir()`, which behaved more like Node.js'
`fs.mkdirSync()` with the `recursive` option set to `true` (i.e.
creating any missing parent directories and succeeding if the directory
exists already).
This commit fixes this inconsistency by removing the `mkdir()` method,
which was not used anyway and only keeping `ensureDir()` (which is
consistent across our different `FileSystem` implementations).
PR Close#33237
When `ngcc` is running in parallel mode (usually when run from the
command line) and the `createNewEntryPointFormats` option is set to true
(e.g. via the `--create-ivy-entry-points` command line option), it can
happen that two workers end up trying to create the same directory at
the same time. This can lead to a race condition, where both check for
the directory existence, see that the directory does not exist and both
try to create it, with the second failing due the directory's having
already been created by the first one. Note that this only affects
directories and not files, because `ngcc` tasks operate on different
sets of files.
This commit avoids this race condition by allowing `FileSystem`'s
`ensureDir()` method to not fail if one of the directories it is trying
to create already exists (and is indeed a directory). This is fine for
the `ensureDir()` method, since it's purpose is to ensure that the
specified directory exists. So, even if the `mkdir()` call failed
(because the directory exists), `ensureDir()` has still completed its
mission.
Related discussion: https://github.com/angular/angular/pull/33049#issuecomment-540485703
FW-1635 #resolve
PR Close#33237
Often the types of an `@Input`'s field don't fully reflect the types of
assignable values. This can happen when an input has a getter/setter pair
where the getter always returns a narrow type, and the setter coerces a
wider value down to the narrow type.
For example, you could imagine an input of the form:
```typescript
@Input() get value(): string {
return this._value;
}
set value(v: {toString(): string}) {
this._value = v.toString();
}
```
Here, the getter always returns a `string`, but the setter accepts any value
that can be `toString()`'d, and coerces it to a string.
Unfortunately TypeScript does not actually support this syntax, and so
Angular users are forced to type their setters as narrowly as the getters,
even though at runtime the coercion works just fine.
To support these kinds of patterns (e.g. as used by Material), this commit
adds a compiler feature called "input coercion". When a binding is made to
the 'value' input of a directive like MatInput, the compiler will look for a
static function with the name ngCoerceInput_value. If such a function is
found, the type-checking expression for the input will be wrapped in a call
to the function, allowing for the expression of a type conversion between
the binding expression and the value being written to the input's field.
To solve the case above, for example, MatInput might write:
```typescript
class MatInput {
// rest of the directive...
static ngCoerceInput_value(value: {toString(): string}): string {
return null!;
}
}
```
FW-1475 #resolve
PR Close#33243
As a hack to get the Ivy compiler ngtsc off the ground, the existing
'allowEmptyCodegenFiles' option was used to control generation of ngfactory
and ngsummary shims during compilation. This option was selected since it's
enabled in google3 but never enabled in external projects.
As ngtsc is now mature and the role shims play in compilation is now better
understood across the ecosystem, this commit introduces two new compiler
options to control shim generation:
* generateNgFactoryShims controls the generation of .ngfactory shims.
* generateNgSummaryShims controls the generation of .ngsummary shims.
The 'allowEmptyCodegenFiles' option is still honored if either of the above
flags are not set explicitly.
PR Close#33256
Angular v9 schematics should print out a link to the migration
guide associated with each schematic. This way, users have an
easy way to find more information about the automatic code
transformations they will see with `ng update`.
PR Close#33258
With Ivy the `entryComponents` array isn't necessary anymore. These changes mark it as deprecated so that it can be removed in a future version.
PR Close#33205
Currently if a `ModuleWithProviders` is missng its generic type, we throw a cryptic error like:
```
error TS-991010: Value at position 3 in the NgModule.imports of TodosModule is not a reference: [object Object]
```
These changes add a better error to make it easier to debug.
PR Close#33187
Resubmit #31168 now that google3 tests can pass. This requires http://cl/272696717 to be patched.
Original description from jasonaden:
Without this change when using UrlTree redirects in urlUpdateStrategy="eager", the URL would get
updated to the target location, then redirected. This resulted in having an additional entry in the
history and thus the back button would be broken (going back would land on the URL causing a new
redirect).
Additionally, there was a bug where the redirect, even without urlUpdateStrategy="eager", could
create a history with too many entries. This was due to kicking off a new navigation within the
navigation cancelling logic. With this PR the new navigation is pushed to the next tick with a
setTimeout, allowing the page being redirected from to be cancelled before starting a new
navigation.
Related to #27148
fix(router): adjust UrlTree redirect to replace URL if in eager update
Fix lint errors
PR Close#32988
Until now, the template type checker has not checked any of the event
bindings that could be present on an element, for example
```
<my-cmp
(changed)="handleChange($event)"
(click)="handleClick($event)"></my-cmp>
```
has two event bindings: the `change` event corresponding with an
`@Output()` on the `my-cmp` component and the `click` DOM event.
This commit adds functionality to the template type checker in order to
type check both kind of event bindings. This means that the correctness
of the bindings expressions, as well as the type of the `$event`
variable will now be taken into account during template type checking.
Resolves FW-1598
PR Close#33125
In ES5 modules, the class declarations consist of an IIFE with inner
and outer declarations that represent the class. The `EsmReflectionHost`
has logic to ensure that `getDeclarationOfIdentifier()` always returns the
outer declaration.
Before this commit, if an identifier referred to an alias of the inner
declaration, then `getDeclarationOfIdentifier()` was failing to find
the outer declaration - instead returning the inner declaration.
Now the identifier is correctly resolved up to the outer declaration
as expected.
This should fix some of the failing 3rd party packages discussed in
https://github.com/angular/ngcc-validation/issues/57.
PR Close#33252
This commit removes `@angular-devkit/build-angular` from package.json
for a project that opts into Bazel. This is because the package adds a
dependency on node-sass, which is rejected by Bazel due to its absense.
This commit also appends to `scripts.postinstall` if it already exists.
This is needed because `ng new` in CLI v9 now automatically adds a
postinstall step for `ngcc`.
PR Close#32946
BREAKING CHANGE:
In v5, we deprecated support for the intl API in order to improve the browser support. We are now removing these deprecated APIs for v9. See the original change here for more info on why: #18284.
PR Close#29250
This commit fixes ngtsc's import generator to use the ReflectionHost when
looking through the exports of an ES module to find the export of a
particular declaration that's being imported. This is necessary because
some module formats like CommonJS have unusual export mechanics, and the
normal TypeScript ts.TypeChecker does not understand them.
This fixes an issue with ngcc + CommonJS where exports were not being
enumerated correctly.
FW-1630 #resolve
PR Close#33192
Normally, when ngcc encounters a package with missing dependencies while
attempting to determine a compilation ordering, it will ignore that package.
This commit adds a configuration for a flag to tell ngcc to compile the
package anyway, regardless of any missing dependencies.
FW-1931 #resolve
PR Close#33192
In the ReflectionHost API, a 'viaModule' indicates that a particular value
originated in another absolute module. It should always be 'null' for values
originating in relatively-imported modules.
This commit fixes a bug in the CommonJsReflectionHost where viaModule would
be reported even for relatively-imported values, which causes invalid import
statements to be generated during compilation.
A test is added to verify the correct behavior.
FW-1628 #resolve
PR Close#33192
This allows disabling parallelism in ngcc if desired, which is mainly useful
for debugging. The implementation creates the flag and passes its value to
mainNgcc.
No tests are added since the feature mainly exists already - ngcc supports
both parallel and serial execution. This commit only allows switching the
flag via the commandline.
PR Close#33192
Prior to this commit, the absolute spans (relative to template source
file rather than the start of an expression) of expressions in a
template attribute like `*ngIf` were generated incorrectly, equating to
the relative spans.
This fixes the bug by passing an `absoluteOffset` parameter when parsing
template bindings.
Through some levels of indirection, this is required for the Language
Service to support text replacement in
https://github.com/angular/angular/pull/33091.
PR Close#33189
These were getting included in the @angular/localize package.
Instead, patch the upstream files to work with TS typeRoots option
See bazelbuild/rules_nodejs#1033
PR Close#33226
Prior to this fix if a map-based class or style binding wrote
its values onto an elemenent, the internal styling context would
not register the binding if the initial value as a `NO_CHANGE`
value. This situation occurs if a directive takes control of the
`class` or `style` input values and then returns a `NO_CHANGE` value
if the initial value is empty.
This patch ensures that all bindings are always registered with the
`TStylingContext` data-structure even if their initial value is
an instance of `NO_CHANGE`.
PR Close#33236
Prior to this fix, all style/class bindings (e.g. `[style]` and
`[class.foo]`) would quietly update a binding value if and when the
current binding value changes during checkNoChanges.
With this patch, all styling instructions will properly check to see
if the value has changed during the second pass of detectChanges()
if checkNoChanges is active.
PR Close#33103
Prior to this commit, metadata defined on ICU container element was not inherited by the ICU if the whole message is a single ICU (for example: `<ng-container i18n="meaning|description@@id">{count, select, ...}</ng-container>). This commit updates the logic to use parent container i18n meta information for the cases when a message consists of a single ICU.
Fixes#33171
PR Close#33191
LocaleID defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngLocaleIdDef to loc. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
PR Close#33212
Previously, when `ngcc` was reflecting on class members it did not
account for the fact that a member could be of the kind
`IndexSignature`. This can happen, for example, on abstract classes (as
is the case for [JsonCallbackContext][1]).
Trying to reflect on such members (and failing to recognize their kind),
resulted in warnings, such as:
```
Warning: Unknown member type: "[key: string]: (data: any) => void;
```
While these warnings are harmless, they can be confusing and worrisome
for users.
This commit avoids such warnings by detecting class members of the
`IndexSignature` kind and ignoring them.
[1]: https://github.com/angular/angular/blob/4659cc26e/packages/common/http/src/jsonp.ts#L39
PR Close#33198
Turns out that writing to global state is more expensive than writing to
a property on an object.
Slower:
````
let count = 0;
function increment() {
count++;
}
```
Faster:
````
const state = {
count: 0
};
function increment() {
state.count++;
}
```
This change moves all of the instruction state into a single state object.
`noop_change_detection` benchmark
Pre refactoring: 16.7 us
Post refactoring: 14.523 us (-13.3%)
PR Close#33093
Prior to this commit, all `className` inputs were not set because the runtime code assumed that the `classMap` instruction is only generated for `[class]` bindings. However the `[className]` binding also produces the same `classMap`, thus the code needs to distinguish between `class` and `className`. This commit adds extra logic to select the right input name and also throws an error in case `[class]` and `[className]` bindings are used on the same element simultaneously.
PR Close#33188
Prior to this change, the template type checker would incorrectly bind
non-property bindings such as `[class.strong]`, `[style.color]` and
`[attr.enabled]` to directive inputs of the same name. This is
undesirable, as those bindings are never actually bound to the inputs at
runtime.
Fixes#32099Fixes#32496
Resolves FW-1596
PR Close#33130
This patch introduces the `printTable()` and `printSources()`
methods to `DebugStylingContext` which can be used via the
`window.ng.getDebugNode` helpers when debugging an application.
PR Close#33179
This commit speeds up the tests by calling `MockHost.reset()` in
`beforeEach()` instead of destroying the entire language service and
creating a new one. The creation of a new language service instance is
expensive due to the need to initialize many core Symbols when creating
a new program.
This speeds ups the test (on my local machine) from 35 secs to 15 secs.
PR Close#33200
Injectable defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngInjectableDef to "prov" (for "provider", since injector defs
are known as "inj"). This is because property names cannot
be minified by Uglify without turning on property mangling
(which most apps have turned off) and are thus size-sensitive.
PR Close#33151
Injector defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngInjectorDef to inj. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
PR Close#33151
This change assures that data structures related to initial inputs
(ones set from static attributes) are created only once (during the
first template pass) and no additional runtime checks are done for
subsequent passes.
Additionally this commit changes the data structure used by initial inputs
on TNode - previously initial inputs for a directive were stored at the
directive index in LView. This meant that an array holding initial inputs
was relativelly big and had many null elements (as placeholders for elements,
directives, injector etc.). After the change we only create an array of a size
equal to a number of directives matched on a given TNode.
For the `directive_instantiate` benchmark it boils to allocating a 1-element
array vs. 100-element array previously.
PR Close#33195
These were getting included in the @angular/localize package.
Instead, patch the upstream files to work with TS typeRoots option
See bazelbuild/rules_nodejs#1033
PR Close#33176
There are many specs in `ts_plugin_spec.ts` that exercise the behavior
of completions. These specs should belong in `completions_spec` instead.
In addition,
1. Tests for `getExternalFiles()` added in `ts_plugin_spec.ts`
2. Fixed bug in MockHost.reset() to remove overriden script names
3. Add test for TS diagnostics when `angularOnly = true` is not set
PR Close#33159
The `legacyMessageIdFormat` is taken from the `i18nInFormat` property but we were only considering
`xmb`, `xlf` and `xlf2` values.
The CLI also supports `xliff` and `xliff2` values for the
`i18nInFormat`.
This commit adds support for those aliases.
PR Close#33160
Prior to this commit, Ivy runtime asserted that a given element is an instance of a DOM node. These asserts may not be correct in case custom renderer is used, which operates objects with a shape different than DOM nodes. This commit updates the code to avoid the mentioned checks in case procedural renderer is used.
PR Close#33156
Prior to this patch, if a map-class binding is applied directly then
that value will be incorrectly provided a sanitizer even if there is no
sanitization present for an element.
PR Close#33154
Now, hovering over an attribute on an element will provide information
about the directive that attribute matches in the element, if any.
(More generally, we return information about directive symbols
matched on an element attribute.)
I believe this is similar to how the indexer provides this kind of
information, though more precise in the sense that this commit provides
directive information only if the directive selector exactly matches the
attribute selector. In another sense, this is a limitation.
In fact, there are the limitations of:
- Directives matched on the element, but with a selector of anything
more than the attribute (e.g. `div[string-model]` or
`[string-model][other-attr]`) will not be returned as symbols matching
on the attribute.
- Only one symbol can be returned currently. If the attribute matches
multiple directives, only one directive symbol will be returned.
Furthermore, we cannot say that the directive symbol returned is
determinstic.
Resolution of these limitations can be discussed in the future. At least
the second limitation should be very easy to fixup in a future commit.
This relies solely on the template compiler and is agnostic to any Ivy
changes, so this is strictly a feature enhancement that will not have to
be refactored when we migrate the language service to Ivy.
PR Close#33127
This PR adds es2015 lib to the `tsconfig.json` of the test project so
that `Promise` could be used. Note this only affects diagnostics in the
IDE. The tsconfig in Language Service Mock Host is the actual config
values used, and it already has es2015 lib.
- Other minor cleanup: Rename imports in `main.ts`.
- Add more cases to `parsing-cases.ts`, which are tested in later PRs
PR Close#33157
Module defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngModuleDef to mod. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
PR Close#33142
Pipe defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngPipeDef to pipe. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
PR Close#33142
Add a new flag to `localize-translate` that allows the
source locale to be specified. When this locale is
provided an extra copy of the files is made for this
locale where the is no translation but all the calls to
`$localize` are stripped out.
Resolves FW-1623
PR Close#33101
Enables providing information about the NgModule a component is in when
its selector is hovered on in a template. Also enables differentiation
of a component and a directive when a directive class name is hovered
over in a TypeScript file.
Next step is to enable hover information for directives.
Part of #32565.
PR Close#33118
Factory defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngFactoryDef to fac. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
Note that the other "defs" (ngPipeDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.
PR Close#33116
Some changes in rules_nodejs providers folded into @angular/bazel package:
* `NodeModuleSources` renamed to `NpmPackageInfo` and now loaded from `//internal/common:npm_package_info.bzl`
* `collect_node_modules_aspect` renamed to `node_modules_aspect`
* new JS provider `JSNamedModuleInfo` now available and ng_module provides it using the `js_named_module_info` factory function
* sources_aspect has also been removed so the use of the `node_sources` legacy provider has been replaced with `JSNamedModuleInfo`.
PR Close#33073
Prior to this change, a static attribute that corresponds with a
directive's input would not be type-checked against the type of the
input. This is unfortunate, as a static value always has type `string`,
whereas the directive's input type might be something different. This
typically occurs when a developer forgets to enclose the attribute name
in brackets to make it a property binding.
This commit lets static attributes be considered as bindings with string
values, so that they will be properly type-checked.
PR Close#33066
This commit introduces an internal config option of the template type
checker that allows to disable strict null checks of input bindings to
directives. This may be particularly useful when a directive is from a
library that is not compiled with `strictNullChecks` enabled.
Right now, strict null checks are enabled when `fullTemplateTypeCheck`
is turned on, and disabled when it's off. In the near future, several of
the internal configuration options will be added as public Angular
compiler options so that users can have fine-grained control over which
areas of the template type checker to enable, allowing for a more
incremental migration strategy.
PR Close#33066
Prior to this change, the template type checker would always allow a
value of type `undefined` to be passed into a directive's inputs, even
if the input's type did not allow for it. This was due to how the type
constructor for a directive was generated, where a `Partial` mapped
type was used to allow for inputs to be unset. This essentially
introduces the `undefined` type as acceptable type for all inputs.
This commit removes the `Partial` type from the type constructor, which
means that we can no longer omit any properties that were unset.
Instead, any properties that are not set will still be included in the
type constructor call, having their value assigned to `any`.
Before:
```typescript
class NgForOf<T> {
static ngTypeCtor<T>(init: Partial<Pick<NgForOf<T>,
'ngForOf'|'ngForTrackBy'|'ngForTemplate'>>): NgForOf<T>;
}
NgForOf.ngTypeCtor(init: {ngForOf: ['foo', 'bar']});
```
After:
```typescript
class NgForOf<T> {
static ngTypeCtor<T>(init: Pick<NgForOf<T>,
'ngForOf'|'ngForTrackBy'|'ngForTemplate'>): NgForOf<T>;
}
NgForOf.ngTypeCtor(init: {
ngForOf: ['foo', 'bar'],
ngForTrackBy: null as any,
ngForTemplate: null as any,
});
```
This change only affects generated type check code, the generated
runtime code is not affected.
Fixes#32690
Resolves FW-1606
PR Close#33066
Currently, method `getVarDeclarations()` does not try to resolve the type of
exported variable from *ngIf directive. It always returns `any` type.
By resolving the real type of exported variable, it is now possible to use this
type information in language service and provide completions, go to definition
and quick info functionality in expressions that use exported variable.
Also language service will provide more accurate diagnostic errors during
development.
PR Close#33016
Currenly the `missing-injectable` migration only migrates providers referenced from
`@NgModule` definitions. The schematic currently does not cover the migration for
providers referenced in `@Directive` or `@Component` definitions.
We need to handle the following keys for directives/components:
- `@Directive` -> `providers`
- `@Component` -> `providers` and `viewProviders`.
This commit ensures that the migration handles providers for these
definitions.
PR Close#33011
When responses are cached ok during sw initialization,
but caching throws an error when handling api response,
this response never gets to client. Fix response
delivery by catching errors, add logging and 2 test cases.
Fixes#21412
PR Close#32996
Make safe caching and unsafe caching methods compatible so they can be
swapped. Gives more flexibility when writing http response processing
code.
PR Close#32996
Currently, the spans of expressions are recorded only relative to the
template node that they reside in, not their source file.
Introduce a `sourceSpan` property on expression ASTs that records the
location of an expression relative to the entire source code file that
it is in. This may allow for reducing duplication of effort in
ngtsc/typecheck/src/diagnostics later on as well.
Child of #31898
PR Close#31897
BREAKING CHANGE:
We no longer directly have a direct depedency on `tslib`. Instead it is now listed a `peerDependency`.
Users not using the CLI will need to manually install `tslib` via;
```
yarn add tslib
```
or
```
npm install tslib --save
```
PR Close#32167
There are numerous approaches to downlevelling backticked
template strings to ES5.
This commit handles yet another one that Babel applies.
PR Close#33097
In Babel `NodePath` objects have more useful information available than
simple AST nodes. But they are more difficult to create, especially for testing.
This commit prepares the way for parsing more complex code downlevelling
scenarios.
PR Close#33097
Previously, the list of missing dependencies was not explicitly joined,
which resulted in the default `,` joiner being used during
stringification.
This commit explicitly joins the missing dependency lines to avoid
unnecessary commas.
Before:
```
The target entry-point "some-entry-point" has missing dependencies:
- dependency 1
, - dependency 2
, - dependency 3
```
After:
```
The target entry-point "some-entry-point" has missing dependencies:
- dependency 1
- dependency 2
- dependency 3
```
PR Close#33139
Previously, the executable for the Angular Compatibility Compiler
(`ngcc`) was called `ivy-ngcc`. This would be confusing for users not
familiar with our internal terminology, especially given that we call it
`ngcc` in all our docs and presentations.
This commit renames the executable to `ngcc` and replaces `ivy-ngcc`
with a script that errors with an informative message (prompting the
user to use `ngcc` instead).
Jira issue: [FW-1624](https://angular-team.atlassian.net/browse/FW-1624)
PR Close#33140
A few specs in `completions_spec.ts` are non-deterministic and do not provide much value to test a specific behavior of language service.
Besides that, they are also slow to run.
PR Close#33120
Remove the following methods from MockHost:
1. `getMarkerLocations`: Replaced with `getLocationMarkerFor()`
2. `getReferenceMarkers`: Replaced with `getReferenceMarkerFor()`
PR Close#33115
Directive defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
ngDirectiveDef to dir. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
Note that the other "defs" (ngFactoryDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.
PR Close#33110
For elements in a template that look like custom elements, i.e.
containing a dash in their name, the template type checker will now
issue an error with instructions on how the resolve the issue.
Additionally, a property binding to a non-existent property will also
produce a more descriptive error message.
Resolves FW-1597
PR Close#33064
Component defs are not considered public API, so the property
that contains them should be prefixed with Angular's marker
for "private" ('ɵ') to discourage apps from relying on def
APIs directly.
This commit adds the prefix and shortens the name from
`ngComponentDef` to `cmp`. This is because property names
cannot be minified by Uglify without turning on property
mangling (which most apps have turned off) and are thus
size-sensitive.
Note that the other "defs" (ngDirectiveDef, etc) will be
prefixed and shortened in follow-up PRs, in an attempt to
limit how large and conflict-y this change is.
PR Close#33088
Based on the results of the `directive_instantiate` executing host
bindings logic (in creation mode) account for ~23% of time spent in
the directive instantiation, even if a directive doesn't have host
bindings! This is clearly wastful hence a new flag.
PR Close#33102
Removes the deprecated `ngForm` element selector and all of the code related to it.
BREAKING CHANGES:
* `<ngForm></ngForm>` can no longer be used as a selector. Use `<ng-form></ng-form>` instead.
* The `NgFromSelectorWarning` directive has been removed.
* `FormsModule.withConfig` has been removed. Use the `FormsModule` directly.
PR Close#33058
There is some confusion around which `NavigationExtras` values are used
by createUrlTree. This specifies that only values that change the URL
are used. This came up during the discussion in #27148.
PR Close#33029
It is now possible to include a set of default ngcc configurations
that ship with ngcc out of the box. This allows ngcc to handle a
set of common packages, which are unlikely to be fixed, without
requiring the application developer to write their own configuration
for them.
Any packages that are configured at the package or project level
will override these default configurations. This allows a reasonable
level of control at the package and user level.
PR Close#33008
This patch enables a styling debug instance (which is apart of the
`debugNode.styles` or `debugNode.classes` data structures) to expose
its context value so that it can be easily debugged.
PR Close#32856
The current `typings` value in `package.json` causes the import of
`@angular/language-service` in TypeScript to be generated as
```
const language_service_1 = require("@angular/language-service/language-service");
```
in CJS output.
This breaks the import shim that overwrites the behavior of `require` at
runtime. Changing the typings to `index.d.ts` fixes the issue.
PR Close#33043
For v9 we want the migration to the new i18n to be as
simple as possible.
Previously the developer had to positively choose to use
legacy messsage id support in the case that their translation
files had not been migrated to the new format by setting the
`legacyMessageIdFormat` option in tsconfig.json to the format
of their translation files.
Now this setting has been changed to `enableI18nLegacyMessageFormat`
as is a boolean that defaults to `true`. The format is then read from
the `i18nInFormat` option, which was previously used to trigger translations
in the pre-ivy angular compiler.
PR Close#33053
Prior to this fix, whenever a style or class binding is present, the
binding application process would require an instance of `TStylingContext`
to be built regardless of whether or not any binding resolution is needed
(just so that it knows whether or not there are any collisions).
This check is, however, unnecessary because if (and only if) there
are directives present on the element then are collisions possible.
This patch removes the need for style/class bindings to register
themselves on to a `TStylingContext` if there are no directives and
present on an element. This means that all map and prop-based
style/class bindings are applied as soon as bindings are updated on
an element.
PR Close#32919
We used to have a custom version of the NodeInjectorFactory check that was
supposed to be faster to the direct usage of the `instanceof` operator. This
might have been the case in the past but the recent benchmark shows that using
`instanceof` speeds up the `directive_instantiate` by ~10%
(from time getting from ~340ms down to ~305ms).
PR Close#33082
A PR that updates one of the benchmarks and another one that changes the signature for `elementStart` got in around the same time which is causing a compilation error. These changes fix the error.
PR Close#33067
This commit implements a tool that will inline translations and generate
a translated copy of a set of application files from a set of translation
files.
PR Close#32881
Currently Ivy stores the element attributes into an array above the component def and passes it into the relevant instructions, however the problem is that upon minification the array will get a unique name which won't compress very well. These changes move the attributes array into the component def and pass in the index into the instructions instead.
Before:
```
const _c0 = ['foo', 'bar'];
SomeComp.ngComponentDef = defineComponent({
template: function() {
element(0, 'div', _c0);
}
});
```
After:
```
SomeComp.ngComponentDef = defineComponent({
consts: [['foo', 'bar']],
template: function() {
element(0, 'div', 0);
}
});
```
A couple of cases that this PR doesn't handle:
* Template references are still in a separate array.
* i18n attributes are still in a separate array.
PR Close#32798
Accessing a string's character at index allocates a new, single character string.
A better (faster) check is to use `charCodeAt` that doesn't trigger allocation.
This simple change speeds up the element_text_create benchmark by ~7%.
PR Close#32997
The history_server rule is not longer shipped with rules_nodejs as it has been replaced by auto-generated rule `load("@npm//history-server:index.bzl", "history_server")` which requires the user to add history-server to their package.json.
PR Close#32889
Removes the `Renderer` and related symbols which have been deprecated since version 4.
BREAKING CHANGES:
* `Renderer` has been removed. Use `Renderer2` instead.
* `RenderComponentType` has been removed. Use `RendererType2` instead.
* `RootRenderer` has been removed. Use `RendererFactory2` instead.
PR Close#33019
Currently the `ngForOf` input accepts `null` or `undefined` as valid
values. Although when using strict template input type checking
(which will be supported by `ngtsc`), passing `null` or `undefined`
with strict null checks enabled causes a type check failure because
the type for the `ngForOf` input becomes too strict if strict null checks
are enabled. The type of the input needs to be expanded to also accept
`null` or `undefined` to behave consistently regardless of the
`strictNullChecks` flag.
This is necessary because whenever strict input type checking is enabled
by default, most of the Angular projects that use `*ngFor` with the async pipe
will either need to disable template type checking or strict null checks
because the `async` pipe returns `null` if the observable hasn't been
emitted yet.
See for example how this affects the `angular/components` repository and
how much bloat the workaround involves: https://github.com/angular/components/pull/16373/files#r296942696.
PR Close#31371
In View Engine, animation metadata could occur in nested arrays which
would be flattened in the compiler. When compiling a component for Ivy
however, the compiler no longer statically evaluates a component's
animation metadata and is therefore unable to flatten it statically.
This resulted in an issue to find animations at runtime, as the metadata
was incorrectly registered with the animation engine.
Although it would be possible to statically evaluate the animation
metadata in ngtsc, doing so would prevent reusable animations exported
from libraries from being usable as ngtsc's partial evaluator is unable
to read values inside libraries. This is unlike ngc's usage of static
symbols represented in a library's `.metadata.json`, which explains how
the View Engine compiler is able to flatten the animation metadata
statically.
As an alternative solution, the metadata flattening is now done in the
runtime during the registration of the animation metadata with the
animation engine.
Fixes#32794
PR Close#32818
As mentioned in the previous commit, the regexp used by
`Validators.email()` is a slightly enhanced version of the
[WHATWG one](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
This commit refactors the regexp (without changing its behavior) to make
it more closely match the format of WHATWG version, so that it is easier
for people to compare it against the WHATWG one and understand the
differences.
The main changes were:
- Changing the order of characters/character classes inside `[...]`;
e.g. `[A-Za-z]` --> `[a-zA-Z]`
- Mark all groups as non-capturing (since we do not use the captured
values); e.g. `(foo)` --> `(?:foo)`
(This could theoretically also have a positive performance impact, but
I suspect JavaScript engines are already optimizing away capturing
groups when they are not used.)
PR Close#32961
Previously, there was no documentation of what `Validators.email()`
expects as a valid e-mail address, making it difficult for people to
determine whether it covers their requirements or not. Even more so that
the used pattern slightly deviates from the
[WHATWG version](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
One's only option was to look at the source code and try to decipher the
regexp pattern.
This commit adds a high-level description of the validator and mentions
its similarity to and differences from the WHATWG version. It also adds
a brief explanation of the regexp's behavior and references for more
information in the source code to provide more context to
maintainers/users trying to understand the implementation in the future.
Fixes#18985Fixes#25186Closes#32747
PR Close#32961
Prior to this change, ng-reflect properties were not created in case an attribute was marked as translatable (for ex. `i18n-title`). This commit adds the logic to generate ng-reflect for such cases.
PR Close#32989
The schematics added in #32791 is currently failing as the package.json does not reference it.
```
> ng add @angular/localize@9.0.0-next.9
+ @angular/localize@9.0.0-next.9
added 1 package from 1 contributor in 6.745s
Installed packages for tooling via npm.
The package that you are trying to add does not support schematics. You can try using a different version of the package or contact the package author to add ng-add support.
```
PR Close#33025
Prior to this commit, the `ng` was exposed in global namespace, which turned out to be problematic when minifying code with Closure, since it sometimes clobber our `ng` global. This commit aligns Ivy debugging tools behavior with existing logic in "platform-browser" package (packages/platform-browser/src/dom/util.ts#L31) by avoiding `ng` in global namespace when Closure Compiler is used.
PR Close#33010
Re-enables the dynamic queries migration, now that we have all of the necessary framework changes in place.
Also moves the logic that identifies static queries out of the compiler and into the static queries migration, because that's the only place left that's using it.
PR Close#32992
Followup to #32720 that removed the logic that statically determines whether a query is dynamic.
This updates the docs to reflect that, and mentions that the flag now defaults to false.
PR Close#32993
Current we need to create and override certain compiler host methods in every schematic because schematics use a virtual fs. We this change we extract this logic to a common util.
PR Close#32827
Not sure why it works on other people's environments, but after
217db9b21 I started getting the following error when running
`scripts/build-packages-dist.sh` (on Windows):
```
ERROR: C:/.../angular/packages/bazel/docs/BUILD.bazel:3:1: Generating Skylark documentation dir for docs (3 files) failed (Exit 1)
Traceback (most recent call last):
File "c:\...\temp\Bazel.runfiles_u_l5te\runfiles\io_bazel_skydoc\skydoc\main.py", line 335, in <module>
main(sys.argv)
File "c:\...\temp\Bazel.runfiles_u_l5te\runfiles\io_bazel_skydoc\skydoc\main.py", line 303, in main
load_symbols = load_sym_extractor.extract(bzl_file)
File "c:\...\temp\Bazel.runfiles_u_l5te\runfiles\io_bazel_skydoc\skydoc\load_extractor.py", line 110, in extract
load_symbols = self._extract_loads(bzl_file)
File "c:\...\temp\Bazel.runfiles_u_l5te\runfiles\io_bazel_skydoc\skydoc\load_extractor.py", line 38, in _extract_loads
tree = ast.parse(f.read(), bzl_file)
File "C:\...\.windows-build-tools\python27\lib\ast.py", line 37, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File "packages/bazel/src/ng_package/ng_package.bzl", line 39
print("[ng_package.bzl]", *args)
^
SyntaxError: invalid syntax
```
It seems expected, because `print` is not a function, so
`print(foo, *args)` is interpreted as printing a tuple (where `*args` is
invalid syntax). Not sure why it doesn't break on other people's
machines :/
This change makes the verbose logs a little less pretty, but that
shouldn't be a big issue (given that it is an opt-in feature and it can
always be overwritten locally, if necessary).
PR Close#32923
The creation of StaticReflector in createMetadataResolver() is a very expensive operation because it involves numerous module resolutions.
To make matter worse, since the API of the Reflector does not provide the ability to invalidate its internal caches, it has to be destroyed and recreated on *every* program change.
This has a HUGE impact on performance.
This PR fixes this problem by carefully invalidating all StaticSymbols in a file that has changed, thereby reducing the overhead of recomputation on program change.
PR Close#32543
This is a re-submit of #32686.
Switches back to having the static flag be optional on ViewChild and ContentChild queries, in preparation for changing its default value.
PR Close#32986
These changes switch to defaulting the `static` flag on `ViewChild` and `ContentChild` queries to `false`, in addition to removing the logic that statically determines whether a query is dynamic.
PR Close#32720
The `$localize` library uses a new message digest function for
computing message ids. This means that translations in legacy
translation files will no longer match the message ids in the code
and so will not be translated.
This commit adds the ability to specify the format of your legacy
translation files, so that the appropriate message id can be rendered
in the `$localize` tagged strings. This results in larger code size
and requires that all translations are in the legacy format.
Going forward the developer should migrate their translation files
to use the new message id format.
PR Close#32937
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add additional coverage and fix spacing
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add additional coverage and fix spacing
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add additional coverage and fix spacing
test(upgrade): add unit tests for AngularJSUrlCodec's parse method
Add unit test coverage for new logic added in #32874 and for existing
logic that was untested.
PR Close#32976
This PR updates Angular to compile with TypeScript 3.6 while retaining
compatibility with TS3.5. We achieve this by inserting several `as any`
casts for compatiblity around `ts.CompilerHost` APIs.
PR Close#32908
Currently the undecorated-classes-with-di migration leverages NGC in order
to work with metadata resolution. Since NGC by default tries to resolve referenced
resources on initialization of the underlying TS program, it can result in unexpected
migration failures due to missing resource files.
This is especially an issue since the CLI wraps the `AngularCompilerProgram` with
special logic (i.e. to support SCSS preprocessing etc.). We don't have all of this since
we instantiate a vanilla NGC program.
The solution to the problem is to simply treat resource requests as valid, and returning
a fake content. The migration is not dependent on templates or stylesheets.. so it's the
simplest and most robust solution.
Fixes#32826
PR Close#32953
ec4381d explicitly set `enableIvy: false` for all migrations inside
the core package. This actually hides migration issues because the
migration itself should ensure that it instantiates the right
compiler program if it relies on `@angular/compiler-cli`.
We should remove these options from all migration tests to
ensure that we catch issues with migrations running in version
9 where Ivy is enabled by default.
e.g. e5636a322c
was accidentally hidden due to the `enableIvy: false` option.
PR Close#32954
ec4381d enabled Ivy by default. This is problematic as migrations
like `static-queries` depend on the `AngularCompilerProgram` (NGC)
in order to perform the migration from version 7 to version 8.
In order to ensure that the migration always runs with NGC
(and doesn't get the `NgtscProgram`), we need to explicitly disable
ivy when creating the `@angular/compiler-cli` program for the migration.
This code is still relevant even though the update from version 7
to version 8 landed. Developers can run `ng update` from version 7
and immediately get to version 9 where Ivy is enabled by default (and in
that case we need to ensure that ngtsc is not accidentally used).
Similar to
e5636a322c.
PR Close#32954
In an attempt to be compatible with previous translation files
the Angular compiler was generating instructions that always
included the message id. This was because it was not possible
to accurately re-generate the id from the calls to `$localize()` alone.
In line with https://hackmd.io/EQF4_-atSXK4XWg8eAha2g this
commit changes the compiler so that it only renders ids if they are
"custom" ones provided by the template author.
NOTE:
When translating messages generated by the Angular compiler
from i18n tags in templates, the `$localize.translate()` function
will compute message ids, if no custom id is provided, using a
common digest function that only relies upon the information
available in the `$localize()` calls.
This computed message id will not be the same as the message
ids stored in legacy translation files. Such files will need to be
migrated to use the new common digest function.
This only affects developers who have been trialling `$localize`, have
been calling `loadTranslations()`, and are not exclusively using custom
ids in their templates.
PR Close#32867
Metadata blocks are delimited by colons. Previously the code naively just
looked for the next colon in the string as the end marker.
This commit supports escaping colons within the metadata content.
The Angular compiler has been updated to add escaping as required.
PR Close#32867
Previously the metadata and placeholder blocks were serialized in
a variety of places. Moreover the code for creating the `LocalizedString`
AST node was doing serialization, which break the separation of concerns.
Now this is all done by the code that renders the AST and is refactored into
helper functions to avoid repeating the behaviour.
PR Close#32867
Previously if a translation contains a placeholder that
does not exist in the message being translated, that
placeholder is evaluated as `undefined`.
Translations should never contain such placeholder names
so now `translate` will throw a helpful error in instead.
PR Close#32867
Adds information about the NgModule a Directive is declared in when the
Directive class name is hovered over, in the form
```
(directive) NgModule.Directive: class
```
Closes#32565
PR Close#32763
Similarly to `ts_library` compilation actions, the `ng_module` compile action should include
the current compile mode in the action description. This makes it consistent with `ts_library`
targets and also avoids confusion when both output flavors are requested.
Currently when both output flavors are requested (e.g. in the `ng_package` rule), both
devmode and prodmode compilations have the same action name. This is confusing and
looks like the given target is built *twice* due to a bug (which is obviously not the case though)
PR Close#32955
With #31953 we moved the factories for components, directives and pipes into a new field called `ngFactoryDef`, however I decided not to do it for injectables, because they needed some extra logic. These changes set up the `ngFactoryDef` for injectables as well.
For reference, the extra logic mentioned above is that for injectables we have two code paths:
1. For injectables that don't configure how they should be instantiated, we create a `factory` that proxies to `ngFactoryDef`:
```
// Source
@Injectable()
class Service {}
// Output
class Service {
static ngInjectableDef = defineInjectable({
factory: () => Service.ngFactoryFn(),
});
static ngFactoryFn: (t) => new (t || Service)();
}
```
2. For injectables that do configure how they're created, we keep the `ngFactoryDef` and generate the factory based on the metadata:
```
// Source
@Injectable({
useValue: DEFAULT_IMPL,
})
class Service {}
// Output
export class Service {
static ngInjectableDef = defineInjectable({
factory: () => DEFAULT_IMPL,
});
static ngFactoryFn: (t) => new (t || Service)();
}
```
PR Close#32433
Safari throws an error when the new URL() constructor is called with an
undefined base. This change checks whether the base is undefined and
then calls the corresponding version of the URL constructor.
fix(upgrade): simplify solution by replacing undefined with ''
Co-Authored-By: Pete Bacon Darwin <pete@bacondarwin.com>
Simplify solution by replacing undefined with ''
Co-Authored-By: Pete Bacon Darwin <pete@bacondarwin.com>
fix(upgrade): Avoid passing an empty string as the base as well.
Browsers other than Safari may have issues with the empty string.
PR Close#32959
Switches back to having the `static` flag be optional on `ViewChild` and `ContentChild` queries, in preparation for changing its default value.
PR Close#32686