With this change we add renovate to update dependencies in the following locations
- WORKSPACE
- integration/bazel/WORKSPACE
- package.json
- packages/**/package.json
- tools/ts-api-guardian/package.json
- aio/package.json
We also enable yarn workspaces so that dependencies in these packages are hoisting to the root and renovate doesn't created nested lock files.
Enabling auto updates is important, because quite often dependencies get out of date especially in the compiler-cli which depends on a number of external dependencies.
PR Close#41407
Introduces an **internal**, **experimental** `profiler` function, which
the runtime invokes around user code, including before and after:
- Running the template function of a component
- Executing a lifecycle hook
- Evaluating an output handler
The `profiler` function invokes a callback set with the global
`ng.ɵsetProfiler`. This API is **private** and **experimental** and
could be removed or changed at any time.
This implementation is cheap and available in production. It's cheap
because the `profiler` function is simple, which allows the JiT compiler
to inline it in the callsites. It also doesn't add up much to the
production bundle.
To listen for profiler events:
```ts
ng.ɵsetProfiler((event, ...args) => {
// monitor user code execution
});
```
PR Close#41255
This commit removes a check for the name of the generated factory
function, which is unimportant to test the behaviour of the code.
The name of these functions is generated from the name of the class
being instantiated. In IE11, there is no `function.name` property available
and so there is a shim for it in `third_party/shims_for_IE.js`, which patches
the `Function.property.name` property.
For performance reasons this shim writes the result of the computation
to the prototype of the function. Unfortunately, this means that any class
that extends the patched class will have the same value for `name`.
PR Close#41416
In #41104 the list of used directives was split into two arrays of used
directives and components, but the JIT side was not updated. This commit
fixes the JIT integration by including the list of used components.
Fixes#41318
PR Close#41353
When possible, the @angular/language-service should only provide
information related to Angular. When there is an embedded language, like
inline templates, editor extensions should have the ability to create
virtual documents and forward the requests to the relevant providers for
that language type (see https://github.com/angular/vscode-ng-language-service/pull/1212).
This commit removes all dom schema completions in both inline and
external templates and provides only the Angular syntax for property completions
on elements.
PR Close#41278
The moved `XhrFactory` still needs to be available from `@angular/common/http`
for some libraries that were built prior to 12.0.0, otherwise they cannot be
used in applications built post-12.0.0.
This commit adds back the re-export of `XhrFactory` and deprecates it.
PR Close#41393
Adds perf tracing for the public methods in LanguageService. If the log level is verbose or higher,
trace performance results to the tsServer logger. This logger is implemented on the extension side
in angular/vscode-ng-language-service.
PR Close#41319
Currently we normalize all CSS property names in the `StylingBuilder` which breaks custom properties, because they're case-sensitive. These changes add a check so that custom properties aren't normalized.
Fixes#41364.
PR Close#41380
Adds a new attribute to the `ng_module` rule that allows users to
set the Angular compiler `compilationMode` flag. An alternative
would have been to just enable the option in the user-specified
tsconfig. Though that is more inconvenient if a Bazel workspace
wants to change the compilation mode conditionally at anaylsis
phase through build settings.
Related to: https://github.com/angular/components/pull/22351t
PR Close#41366
This enumeration will now start to appear in publicly facing code,
as part of declarations, so we remove the R3 to make it less specific
to the internal name for the Ivy renderer/compiler.
PR Close#41231
Each of the annotations had its own function for doing this, and those
methods were generally employing spread operators that could allow
unwanted properties to leak into the factory metadata object.
This commit supplies a shared function `toFactoryMetadata()` that
avoids this spread of properties into the returned function.
PR Close#41231
Now that other values were removed from `R3ResolvedDependencyType`,
its meaning can now be inferred from the other properties in the
`R3DeclareDependencyMetadata` type. This commit removes this enum
and updates the code to work without it.
PR Close#41231
When `ɵngDeclareInjector()` was implemented, the `factory` was moved
out to the `ɵfac` static property on the class. This check was not updated.
PR Close#41231
This instruction was created to work around a problem with injecting a
`ChangeDetectorRef` into a pipe. See #31438. This fix required special
metadata for when the thing being injected was a `ChangeDetectorRef`.
Now this is handled by adding a flag `InjectorFlags.ForPipe` to the
`ɵɵdirectiveInject()` call, which avoids the need to special test_cases
`ChangeDetectorRef` in the generated code.
PR Close#41231
This commit changes the partial compilation so that it outputs declaration
calls rather than compiled factory functions.
The JIT compiler and the linker are updated to be able to handle these
new declarations.
PR Close#41231
Adds a `collectCommentNodes` option on `ParseTemplateOptions` which will cause the returned `ParsedTemplate` to include an array of all html comments found in the template.
PR Close#41251
In some cases, we want to test the AIO app or docs examples against the locally built `angular-in-memory-web-api` for example to ensure that the changes in a commit do not introduce a breaking changes.
PR Close#41313
With this change we move `XhrFactory` to the root entrypoint of `@angular/commmon`, this is needed so that we can configure `XhrFactory` DI token at a platform level, and not add a dependency between `@angular/platform-browser` and `@angular/common/http`.
Currently, when using `HttpClientModule` in a child module on the server, `ReferenceError: XMLHttpRequest is not defined` is being thrown because the child module has its own Injector and causes `XhrFactory` provider to be configured to use `BrowserXhr`.
Therefore, we should configure the `XhrFactory` at a platform level similar to other Browser specific providers.
BREAKING CHANGE:
`XhrFactory` has been moved from `@angular/common/http` to `@angular/common`.
**Before**
```ts
import {XhrFactory} from '@angular/common/http';
```
**After**
```ts
import {XhrFactory} from '@angular/common';
```
Closes#41311
PR Close#41313
A previous commit implemented a streamlined performance metric reporting
system for the compiler-cli, controlled via the compiler option
`tracePerformance`.
This commit adds a custom Bazel flag rule //packages/compiler-cli:ng_perf
to the repository, and wires it through to the `ng_module` implementation
such that if the flag is set, `ng_module` will produce perf results as part
of the build. The underlying mechanism of `//:ng_perf` is not exported from
`@angular/bazel` as a public rule that consumers can use, so there is little
risk of accidental dependency on the contents of these perf traces.
An alias is added so that `--ng_perf` is a Bazel flag which works in our
repository.
PR Close#41125
ngtsc has an internal performance tracing package, which previously has not
really seen much use. It used to track performance statistics on a very
granular basis (microseconds per actual class analysis, for example). This
had two problems:
* it produced voluminous amounts of data, complicating the analysis of such
results and providing dubious value.
* it added nontrivial overhead to compilation when used (which also affected
the very performance of the operations being measured).
This commit replaces the old system with a streamlined performance tracing
setup which is lightweight and designed to be always-on. The new system
tracks 3 metrics:
* time taken by various phases and operations within the compiler
* events (counters) which measure the shape and size of the compilation
* memory usage measured at various points of the compilation process
If the compiler option `tracePerformance` is set, the compiler will
serialize these metrics to a JSON file at that location after compilation is
complete.
PR Close#41125
Some `elements` tests rely on `window.customElements` being available.
On browsers where this was not present, the tests were skipped.
This commit includes the `@webcomponents/custom-elements` polyfill in
order to be able to run all `elements` tests on older browsers, which do
not natively support Custom Elements.
This, also, fixes the [saucelabs_ivy][1] and [saucelabs_view_engine][2]
CI jobs (part of the `monitoring` workflow), which have been failing
recently on IE 11 (probably due to the update to TS 4.2.3).
[1]: https://circleci.com/gh/angular/angular/944291
[2]: https://circleci.com/gh/angular/angular/944289
PR Close#41324
TypeScript 4.2 has changed its emitted syntax for synthetic constructors
when using `downlevelIteration`, which affects ES5 bundles that have
been downleveled from ES2015 bundles. This is typically the case for UMD
bundles in the APF spec, as they are generated by downleveling the
ESM2015 bundle into ES5. The reflection capabilities in the runtime need
to recognize this new form to correctly deal with synthesized
constructors, as otherwise JIT compilation could generate invalid
factory functions.
Fixes#41298
PR Close#41305
TypeScript 4.2 has changed its emitted syntax for synthetic constructors
when using `downlevelIteration`, which affects ES5 bundles that have
been downleveled from ES2015 bundles. This is typically the case for UMD
bundles in the APF spec, as they are generated by downleveling the
ESM2015 bundle into ES5. ngcc needs to detect the new syntax in order to
correctly identify synthesized constructor functions in ES5 bundles.
Fixes#41298
PR Close#41305
Adds a migration that casts the value of `ActivatedRouteSnapshot.fragment` to be non-nullable.
Also moves some code from the `AbstractControl.parent` migration so that it can be reused.
Relates to #37336.
PR Close#41092
The Ivy Language Service uses the compiler's template type-checking engine,
which honors the configuration in the user's tsconfig.json. We recommend
that users upgrade to `strictTemplates` mode in their projects to take
advantage of the best possible type inference, and thus to have the best
experience in Language Service.
If a project is not using `strictTemplates`, then the compiler will not
leverage certain type inference options it has. One case where this is very
noticeable is the inference of let- variables for structural directives that
provide a template context guard (such as NgFor). Without `strictTemplates`,
these guards will not be applied and such variables will be inferred as
'any', degrading the user experience within Language Service.
This is working as designed, since the Language Service _should_ reflect
types exactly as the compiler sees them. However, the View Engine Language
Service used its own type system that _would_ infer these types even when
the compiler did not. As a result, it's confusing to some users why the
Ivy Language Service has "worse" type inference.
To address this confusion, this commit implements a suggestion diagnostic
which is shown in the Language Service for variables which could have been
narrowed via a context guard, but the type checking configuration didn't
allow it. This should make the reason why variables receive the 'any' type
as well as the action needed to improve the typings much more obvious,
improving the Language Service experience.
Fixes angular/vscode-ng-language-service#1155
Closes#41042
PR Close#41072
Currently, when importing `BrowserAnimationsModule`, Angular uses `AnimationRenderer`
as the renderer. When the root view is removed, the `AnimationRenderer` defers the actual
work to the `TransitionAnimationEngine` to do this, and the `TransitionAnimationEngine`
doesn't actually remove the DOM node, but just calls `markElementAsRemoved()`.
The actual DOM node is not removed until `TransitionAnimationEngine` "flushes".
Unfortunately, though, that "flush" will never happen, since the root view is being
destroyed and there will be no more flushes.
This commit adds `flush()` call when the root view is being destroyed.
BREAKING CHANGE:
DOM elements are now correctly removed when the root view is removed.
If you are using SSR and use the app's HTML for rendering, you will need
to ensure that you save the HTML to a variable before destorying the
app.
It is also possible that tests could be accidentally relying on the old behavior by
trying to find an element that was not removed in a previous test. If
this is the case, the failing tests should be updated to ensure they
have proper setup code which initializes elements they rely on.
PR Close#41059
ActivatedRoute.fragment was typed as Observable<string> but could emit
both null and undefined due to incorrect non-null assertion. These
non-null assertions have been removed and fragment has been retyped to
string | null.
BREAKING CHANGE:
Strict null checks will report on fragment potentially being null.
Migration path: add null check.
Fixes#23894, fixes#34197.
PR Close#37336
The `ɵɵInjectorDef` interface is internal and should not be published publicly
as part of libraries. This commit updates the compiler to render an opaque
type, `ɵɵInjectorDeclaration`, for this instead, which appears in the typings
for compiled libraries.
PR Close#41119
Th `ɵɵFactoryDef` type will appear in published libraries, via their typings
files, to describe what type dependencies a DI factory has. The parameters
on this type are used by tooling such as the Language Service to understand
the DI dependencies of the class being created by the factory.
This commit moves the type to the `public_definitions.ts` file alongside
the other types that have a similar role, and it renames it to `ɵɵFactoryDeclaration`
to align it with the other declaration types such as `ɵɵDirectiveDeclaration`
and so on.
PR Close#41119
These types are only used in the generated typings files to provide
information to the Angular compiler in order that it can compile code
in downstream libraries and applications.
This commit aliases these types to `unknown` to avoid exposing the
previous alias types such as `ɵɵDirectiveDef`, which are internal to
the compiler.
PR Close#41119
When there was more than one rule in a single style string, only the first
rule was having its `:host` selector processed correctly. Now subsequent
rules will also be processed accurately.
Fixes#41237
PR Close#41261
Previously presence of both [class] and [className] bindings on an element was treated as compiler error (implemented in 6f203c9575). Later, the situation was improved to actually allow both bindings to co-exist (see a153b61098), however the compiler check was not removed completely. The only situation where the error is thrown at this moment is when static (but with interpolation) and bound `class` attributes are present on an element, for ex.:
```
<div class="{{ one }}" [class]="'two'"></div>
```
In the current situation the error is acually misleading (as it refers to `[className]`).
This commit removes the mentioned compiler check as obsolete and makes the `class` and `style` attribute processing logically the same (the last occurrence is used to compute the value).
PR Close#41254
This commit fixes the behavior when creating a type constructor for a directive when the following
conditions are met.
1. The directive has bound generic parameters.
2. Inlining is not available. (This happens for language service compiles).
Previously, we would throw an error saying 'Inlining is not supported in this environment.' The
compiler would stop type checking, and the developer could lose out on getting errors after the
compiler gives up.
This commit adds a useInlineTypeConstructors to the type check config. When set to false, we use
`any` type for bound generic parameters to avoid crashing. When set to true, we inline the type
constructor when inlining is required.
Addresses #40963
PR Close#41043
For the tests in //packages/compiler-cli/src/ngtsc/typecheck, this
commits uses a `TypeCheckFile` for the environment, rather than a
`FakeEnvironment`. Using a real environment gives us more flexibility
with testing.
PR Close#41043
The partial declaration of a component includes the list of directives
that are used in its template, including some metadata of the directive
which can be used during actual compilation of the component. Used
components are currently part of this list, as components are also
directives. This commit splits the used components into a dedicate
property in the partial declaration, which allows for template
compilation to optimize the generated code for components.
PR Close#41104
This commit complements the support for the `__spreadArray` helper that
was added in microsoft/TypeScript#41523. The prior helpers `__spread`
and `__spreadArrays` used the `__read` helper internally, but the helper
is now emitted as an argument to `__spreadArray` so ngcc now needs to
support evaluating it statically. The real implementation of `__read`
reads an iterable into an array, but for ngcc's static evaluation
support it is sufficient to only deal with arrays as is. Additionally,
the optional `n` parameter is not supported as that is only emitted for
array destructuring syntax, which ngcc does not have to support.
PR Close#41201
In TypeScript 4.2 the `__spread` and `__spreadArrays` helpers were both
replaced by the new helper function `__spreadArray` in
microsoft/TypeScript#41523. These helpers may be used in downleveled
JavaScript bundles that ngcc has to process, so ngcc has the ability to
statically detect these helpers and provide evaluation logic for them.
Because Angular is adopting support for TypeScript 4.2 it becomes
possible for libraries to be compiled by TypeScript 4.2 and thus ngcc
has to add support for the `__spreadArray` helper. The deprecated
`__spread` and `__spreadArrays` helpers are not affected by this change.
Closes#40394
PR Close#41201
This commit makes the `RadioControlRegistry` class tree-shakable by adding the `providedIn` property to its
`@Injectable` decorator. Now if the radio buttons are not used in the app (thus no `RadioControlValueAccessor`
directive is initialized), the `RadioControlRegistry` should not be included into application's prod bundle.
PR Close#41126
This commit makes the `FormBuilder` class tree-shakable by adding the `providedIn` property to its `@Injectable`
decorator. Now if the `FormBuilder` class is not referenced in application's code, it should not be included into
its production bundle.
PR Close#41126
The recently introduced typings-only mode in ngcc would incorrectly
write compiled JavaScript files if typings-only mode was requested, in
case the typings of the entry-point had already been processed in a
prior run of ngcc. The corresponding format property for which the
JavaScript files were written were not marked as processed, though, as
the typings-only mode excluded the format property itself from being
marked as processed. Consequently, subsequent runs of ngcc would not
consider the entry-point to have been processed and recompile the
JavaScript bundle once more, resulting in duplicate ngcc imports.
Fixes#41198
PR Close#41209
This commit changes the partial compilation so that it outputs declaration
calls rather than definition calls for NgModules and Injectors.
The JIT compiler and the linker are updated to be able to handle these
new declarations.
PR Close#41080
There were a number of almost identical interfaces used in
the same way throughout the Render3 compiler code.
This commit changes the compiler to use the same interface
throughout.
PR Close#41080
This function is declared in multiple places. The instances inside
`compiler` are slightly different to those in `compiler-cli`. So this
commit consolidates them into two reusable functions.
PR Close#41080
Currently the `Validators` class contains a number of static methods that represent different validators as well as some helper methods. Since class methods are not tree-shakable, any reference to the `Validator` class retains all of its methods (even if you've used just one).
This commit refactors the code to extract the logic into standalone functions and use these functions in the code instead of referencing them via `Validators` class. That should make the code more tree-shakable. The `Validators` class still retains its structure and calls these standalone methods internally to keep this change backwards-compatible.
PR Close#41189
A long-requested feature for HttpClient is the ability to store and retrieve
custom metadata for requests, especially in interceptors. This commit
implements this functionality via a new context object for requests.
Each outgoing HttpRequest now has an associated "context", an instance of
the HttpContext class. An HttpContext can be provided when making a request,
or if not then an empty context is created for the new request. This context
shares its lifecycle with the entire request, even across operations that
change the identity of the HttpRequest instance such as RxJS retries.
The HttpContext functions as an expando. Users can create typed tokens as instances of HttpContextToken, and
read/write a value for the key from any HttpContext object.
This commit implements the HttpContext functionality. A followup commit will
add angular.io documentation.
PR Close#25751
This commit updates Forms code to avoid direct references to all built-in ControlValueAccessor classes, which
prevents their tree-shaking from production builds. Instead, a new static property is added to all built-in
ControlValueAccessors, which is checked when we need to identify whether a given ControlValueAccessors is a
built-in one.
PR Close#41146
Currently the code in the `FormGroupDirective` assumes that the shape of the underlying `FormGroup` never
changes and `FormControl`s are not replaced with other types. In practice this is possible and Forms code
should be able to process such changes in FormGroup shape.
This commit adds extra check to the `FormGroupDirective` class to avoid applying FormControl-specific to
other types.
Fixes#13788.
PR Close#40829
BREAKING CHANGE:
Switching default of `emitDistinctChangesOnlyDefaultValue`
which changes the default behavior and may cause some applications which
rely on the incorrect behavior to fail.
`emitDistinctChangesOnly` flag has also been deprecated and will be
removed in a future major release.
The previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in an artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail, and it should not be the thing that determines
how often change event should fire.
Unfortunately, fixing the behavior outright caused too many existing
applications to fail. For this reason, Angular considers this fix a
breaking fix and has introduced a flag in `@ContentChildren` and
`@ViewChildren`, that controls the behavior.
```
export class QueryCompWithStrictChangeEmitParent {
@ContentChildren('foo', {
// This option is the new default with this change.
emitDistinctChangesOnly: true,
})
foos!: QueryList<any>;
}
```
For backward compatibility before v12
`emitDistinctChangesOnlyDefaultValue` was set to `false. This change
changes the default to `true`.
PR Close#41121
Tsserver expects `@angular/language-service` to provide a factory function
as the default export (commonjs-style) of the package.
The current implementation side steps TypeScript's import syntax by using
`module.exports = factory`.
This allows the code to incorrectly re-export other symbols:
```ts
export * from './api';
```
which transpiles to:
```js
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("@angular/language-service/api"), exports);
```
Doing this meant that the package now has a runtime dependency on `tslib`,
which is totally unnecessary.
With the proper `export =` syntax, `tslib` is removed, and no other exports
are allowed.
Output:
```js
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/language-service", ["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
return function factory(tsModule) {
var plugin;
return {
create: function (info) {
var config = info.config;
var bundleName = config.ivy ? 'ivy.js' : 'language-service.js';
plugin = require("./bundles/" + bundleName)(tsModule);
return plugin.create(info);
},
getExternalFiles: function (project) {
var _a, _b;
return (_b = (_a = plugin === null || plugin === void 0 ? void 0 : plugin.getExternalFiles) === null || _a === void 0 ? void 0 : _a.call(plugin, project)) !== null && _b !== void 0 ? _b : [];
},
onConfigurationChanged: function (config) {
var _a;
(_a = plugin === null || plugin === void 0 ? void 0 : plugin.onConfigurationChanged) === null || _a === void 0 ? void 0 : _a.call(plugin, config);
},
};
};
});
```
PR Close#41165
The ViewEngine message extraction would trim the values
of the `equiv-text` attributes. This commit aligns the Ivy
extraction of these attributes.
Fixes#41176
PR Close#41180
The `DomAdapter` is present in all Angular apps and its methods aren't tree shakeable.
These changes remove the methods that either aren't being used anymore or were only
used by our own tests. Note that these changes aren't breaking, because the adapter
is an internal API.
The following methods were removed:
* `getProperty` - only used within our own tests.
* `log` - Guaranteed to be defined on `console`.
* `logGroup` and `logGroupEnd` - Only used in one place. It was in the DomAdapter for built-in null checking.
* `logGroupEnd` - Only used in one place. It was placed in the DomAdapter for built in null checking.
* `performanceNow` - Only used in one place that has to be invoked through the browser console.
* `supportsCookies` - Unused.
* `getCookie` - Unused.
* `getLocation` and `getHistory` - Only used in one place which appears to have access to the DOM
already, because it had direct accesses to `window`. Furthermore, even if this was being used
in a non-browser context already, the `DominoAdapter` was set up to throw an error.
The following APIs were changed to be more compact:
* `supportsDOMEvents` - Changed to a readonly property.
* `remove` - No longer returns the removed node.
PR Close#41102
When there are elements in a translated message, the start and end tags
are encoded as placeholders. The names of these placeholders are computed
from the name of the element. For example `<a> will be `START_LINK` and
`</a>` will be `CLOSE_LINK`.
If there are more than one element with the same name, but different attributes,
then the starting placeholder name is made unique.
For example `<a href="a">` would be `START_LINK`, while `<a href="b">` in
the same message would then be called `START_LINK_1`.
But the closing tags will not be made unique since there are no attrbutes;
the always have the same text `</a>`, which will produce, for example,
`CLOSE_LINK`.
Previously, when extracting XLIFF 2 formatted translation files, the closing
tag placeholder names were computed incorrectly from the opening tag
placeholder names. For example `CLOSE_LINK_1`.
This commit strips these `_1` type endings from the start tag placeholder
name when computing the closing tag placeholder name. It also ensures
that the `type` of the placeholder is computed accurately in these cases
too.
Fixes#41142
PR Close#41152
The Angular compiler creates two `ts.Program`s; one for emit and one for
template type-checking. The creation of the type-check program could
benefit from reusing the `ts.ModuleResolutionCache` that was primed
during the creation of the emit program. This requires that the compiler
host implements `resolveModuleNames`, as otherwise TypeScript will setup
a `ts.ModuleResolutionHost` of its own for both programs.
This commit ensures that `resolveModuleNames` is always implemented,
even if the originally provided compiler host does not. This is
beneficial for the `ngc` binary.
PR Close#39693
One of the main goals of the bundling tests is to verify that unused symbols are tree-shaken away in prod bundles.
Currently both Reactive and Template-driven test apps are merged into one. In order to make these tree-shaking
tests even more useful, this commit splits exiting test app into two, so that we can further optimize sets of
symbols that should be retained in both scenarios.
PR Close#41108
Previously, injector definitions contained a `factory` property that
was used to create a new instance of the associated NgModule class.
Now this factory has been moved to its own `ɵfac` static property on the
NgModule class itself. This is inline with how directives, components and
pipes are created.
There is a small size increase to bundle sizes for each NgModule class,
because the `ɵfac` takes up a bit more space:
Before:
```js
let a = (() => {
class n {}
return n.\u0275mod = c.Cb({type: n}),
n.\u0275inj = c.Bb({factory: function(t) { return new (t || n) }, imports: [[e.a.forChild(s)], e.a]}),
n
})(),
```
After:
```js
let a = (() => {
class n {}
return n.\u0275fac = function(t) { return new (t || n) },
n.\u0275mod = c.Cb({type: n}),
n.\u0275inj = c.Bb({imports: [[r.a.forChild(s)], r.a]}),
n
})(),
```
In other words `n.\u0275fac = ` is longer than `factory: ` (by 5 characters)
and only because the tooling insists on encoding `ɵ` as `\u0275`.
This can be mitigated in a future PR by only generating the `ɵfac` property
if it is actually needed.
PR Close#41022
This commit adds a semi-comprehensive README file which describes the
design goals and implementation of the template type checking engine,
which powers the Angular Language Service as well as the main compiler's
understanding of types in templates.
PR Close#41004
The compiler performs cycle analysis for the used directives and pipes
of a component's template to avoid introducing a cyclic import into the
generated output. The used directives and pipes are represented by their
output expression which would typically be an `ExternalExpr`; those are
responsible for the generation of an `import` statement. Cycle analysis
needs to determine the `ts.SourceFile` that would end up being imported
by these `ExternalExpr`s, as the `ts.SourceFile` is then checked against
the program's `ImportGraph` to determine if the import is allowed, i.e.
does not introduce a cycle. To accomplish this, the `ExternalExpr` was
dissected and ran through module resolution to obtain the imported
`ts.SourceFile`.
This module resolution step is relatively expensive, as it typically
needs to hit the filesystem. Even in the presence of a module resolution
cache would these module resolution requests generally see cache misses,
as the generated import originates from a file for which the cache has
not previously seen the imported module specifier.
This commit removes the need for the module resolution by wrapping the
generated `Expression` in an `EmittedReference` struct. This allows the
reference emitter mechanism that is responsible for generating the
`Expression` to also communicate from which `ts.SourceFile` the
generated `Expression` would be imported, precluding the need for module
resolution down the road.
PR Close#40948
The import graph scans source files for its import and export statements
to extract the source files that it imports/exports. Such statements
contain a module specifier string and this module specifier used to be
resolved to the actual source file using an explicit module resolution
step. This is especially expensive in incremental rebuilds, as the
module resolution cache has not been primed during program creation
(assuming that the incremental program was able to reuse the module
resolution results from a prior compilation). This meant that all module
resolution requests would have to hit the filesystem, which is
relatively slow.
This commit is able to replace the module resolution with TypeScript's
bound symbol of the module specifier. This symbol corresponds with the
`ts.SourceFile` that is being imported/exported, which is exactly what
the import graph was interested in. As a result, no filesystem accesses
are done anymore.
PR Close#40948
This is necessary for closure compiler in order to support cross chunk code motion.
I'm intentionally not annotating these call sites with @__PURE__ at the moment because
build-optimizer does it within the Angular CLI build. In the future we might want to consider
having both annotations here in case we change how build-optimizer works.
PR Close#41096
This change marks all relevant define* callsites as pure, causing the compiler to
emmit either @__PURE__ or @pureOrBreakMyCode annotation based on whether we are
compiling code annotated for closure or terser.
This change is needed in g3 where we don't run build optimizer but we
need the code to be annotated for the closure compiler.
Additionally this change allows for simplification of CLI and build optimizer as they
will no longer need to rewrite the generated code (there are still other places where
a build optimizer rewrite will be necessary so we can't remove it, we can only simplify it).
PR Close#41096
Adds a new flag to `localize-extract` called `--migrateMapFile` which will generate a JSON file
that can be used to map legacy message IDs to cannonical ones.
Also includes a new script called `localize-migrate` that can take the mapping file which was
generated by `localize-extract` and migrate all of the IDs in the files that were passed in.
PR Close#41026
In Angular programs, changing a file may require other files to be
emitted as well due to implicit NgModule dependencies. For example, if
the selector of a directive is changed then all components that have
that directive in their compilation scope need to be recompiled, as the
change of selector may affect the directive matching results.
Until now, the compiler solved this problem using a single dependency
graph. The implicit NgModule dependencies were represented in this
graph, such that a changed file would correctly also cause other files
to be re-emitted. This approach is limited in a few ways:
1. The file dependency graph is used to determine whether it is safe to
reuse the analysis data of an Angular decorated class. This analysis
data is invariant to unrelated changes to the NgModule scope, but
because the single dependency graph also tracked the implicit
NgModule dependencies the compiler had to consider analysis data as
stale far more often than necessary.
2. It is typical for a change to e.g. a directive to not affect its
public API—its selector, inputs, outputs, or exportAs clause—in which
case there is no need to re-emit all declarations in scope, as their
compilation output wouldn't have changed.
This commit implements a mechanism by which the compiler is able to
determine the impact of a change by comparing it to the prior
compilation. To achieve this, a new graph is maintained that tracks all
public API information of all Angular decorated symbols. During an
incremental compilation this information is compared to the information
that was captured in the most recently succeeded compilation. This
determines the exact impact of the changes to the public API, which
is then used to determine which files need to be re-emitted.
Note that the file dependency graph remains, as it is still used to
track the dependencies of analysis data. This graph does no longer track
the implicit NgModule dependencies, which allows for better reuse of
analysis data.
These changes also fix a bug where template type-checking would fail to
incorporate changes made to a transitive base class of a
directive/component. This used to be a problem because transitive base
classes were not recorded as a transitive dependency in the file
dependency graph, such that prior type-check blocks would erroneously
be reused.
This commit also fixes an incorrectness where a change to a declaration
in NgModule `A` would not cause the declarations in NgModules that
import from NgModule `A` to be re-emitted. This was intentionally
incorrect as otherwise the performance of incremental rebuilds would
have been far worse. This is no longer a concern, as the compiler is now
able to only re-emit when actually necessary.
Fixes#34867Fixes#40635Closes#40728
PR Close#40947
This commit refactors Ivy runtime code to move `readPatchedData` and `attachPatchedData` functions to a single
location for better maintainability and to make it easier to do further changes if needed. The `readPatchedLView`
function was also moved to the same location (since it's a layer on top of the `readPatchedData` function).
PR Close#41097
For certain generated function calls, the compiler emits a 'PURE' annotation
which informs Terser (the optimizer) about the purity of a specific function
call. This commit expands that system to produce a new Closure-specific
'pureOrBreakMyCode' annotation when targeting the Closure optimizer instead
of Terser.
PR Close#41021
We currently provide completions for DOM elements in the schema as well
as attributes when we are in the context of an external template.
However, these completions are already provided by other extensions for
HTML contexts (like Emmet). To avoid duplication of results, this commit
updates the language service to exclude DOM completions for external
templates. They are still provided for inline templates because those
are not handled by the HTML language extensions.
PR Close#41078
In the new behavior Angular cleanups `popstate` and `hashchange` event listeners
when the root view gets destroyed, thus event handlers are not added twice
when the application is bootstrapped again.
BREAKING CHANGE:
Methods of the `PlatformLocation` class, namely `onPopState` and `onHashChange`,
used to return `void`. Now those methods return functions that can be called
to remove event handlers.
PR Close#31546
PR Close#40867
This commit updates the type of the `APP_INITIALIZER` injection token to
better document the expected types of values that Angular handles. Only
Promises and Observables are awaited and other types of values are ignored,
so the type of `APP_INITIALIZER` has been updated to
`Promise<unknown> | Observable<unknown> | void` to reflect this behavior.
BREAKING CHANGE:
The type of the `APP_INITIALIZER` token has been changed to more accurately
reflect the types of return values that are handled by Angular. Previously,
each initializer callback was typed to return `any`, this is now
`Promise<unknown> | Observable<unknown> | void`. In the unlikely event that
your application uses the `Injector.get` or `TestBed.inject` API to inject
the `APP_INITIALIZER` token, you may need to update the code to account for
the stricter type.
Additionally, TypeScript may report the TS2742 error if the `APP_INITIALIZER`
token is used in an expression of which its inferred type has to be emitted
into a .d.ts file. To workaround this, an explicit type annotation is needed,
which would typically be `Provider` or `Provider[]`.
Closes#40729
PR Close#40986
The codebase currently contains several `EMPTY_OBJ` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating, we decided to remove the duplicated symbols.
This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.
PR Close#41066
These constants were created in a very early phase of Ivy development.
They have never been used in the framework, no the build-optimizer tool.
PR Close#41040
Previously, `ɵɵgetFactoryOf()` was "privately" published from
`@angular/core` since in the past it was assumed that this
might be an instruction generated by the compiler.
This is not currently the case, so this commit removes it from
the private exports and renames it to indicate that it is a local
helper function.
PR Close#41040
This method does not appear to be used in the project.
This commit removes it and code that it exclusively
depended upon, or depended upon it.
PR Close#41040
Before `unknown` was available, the `never` type was used to discourage
application developers from using "private" properties. The `unknown` type
is much better suited for this.
PR Close#41040
The compiler considers template diagnostics to "belong" to the source file
of the component using the template. This means that when diagnostics for
a source file are reported, it returns diagnostics of TS structures in the
actual source file, diagnostics for any inline templates, and diagnostics of
any external templates.
The Language Service uses a different model, and wants to show template
diagnostics in the actual .html file. Thus, it's not necessary (and in fact
incorrect) to include such diagnostics for the actual .ts file as well.
Doing this currently causes a bug where external diagnostics appear in the
TS file with "random" source spans.
This commit changes the Language Service to filter the set of diagnostics
returned by the compiler and only include those diagnostics with spans
actually within the .ts file itself.
Fixes#41032
PR Close#41070
The current logic in the compiler is to bail when there are errors when
parsing a template into an HTML AST or when there are errors in the i18n
metadata. As a result, a template with these types of parse errors
_will not have any information for the language service_. This is because we
never attempt to conver the HTML AST to a template AST in these
scenarios, so there are no template AST nodes for the language service
to look at for information. In addition, this also means that the errors
are never displayed in the template to the user because there are no
nodes to map the error to.
This commit adds an option to the template parser to temporarily ignore
the html parse and i18n meta errors and always perform the template AST
conversion. At the end, the i18n and HTML parse errors are appended to
the returned errors list. While this seems risky, it at least provides
us with more information than we had before (which was 0) and it's only
done in the context of the language service, when the compiler is
configured to use poisoned data (HTML parse and i18n meta errors can be
interpreted as a "poisoned" template).
fixes angular/vscode-ng-language-service#1140
PR Close#41068
An opening tag `<` without any characters after it is interperted as a
text node (just a "less than" character) rather than the start of an
element in the template AST. This commit adjusts the autocomplete engine
to provide element autocompletions when the nearest character to the
left of the cursor is `<`.
Part of the fix for angular/vscode-ng-language-service#1140
PR Close#41068
The compiler's parsing code has logic to recover from incomplete open
tags (i.e. `<div`) but the recovery logic does not handle when the
incomplete tag is terminated by an EOF. This commit updates the logic to
allow for the EOF character to be interpreted as the end of the tag open
so that the parser can continue processing. It will then fail to find
the end tag and recover by marking the open tag as incomplete.
Part of https://github.com/angular/vscode-ng-language-service/issues/1140
PR Close#41054
This commit adds a new configuration option, `forceStrictTemplates` to the
language service plugin to allow users to force enable `strictTemplates`.
This is needed so that the Angular extension can be used inside Google without
changing the underlying compiler options in the `ng_module` build rule.
PR Close#41062
VSCode only de-duplicates references results for "go to references" requests
but does not de-duplicate them for "find all references" requests. The
result is that users see duplicate references for results in TypeScript
files - one from the built-in TS extension and one from us.
While this is an issue in VSCode (see https://github.com/microsoft/vscode/issues/117095)
this commit provides a quick workaround on our end until it can be addressed there.
This commit should be reverted when microsoft/vscode/issues/117095 is resolved.
fixes https://github.com/angular/vscode-ng-language-service/issues/1124
PR Close#41041
1. The error function throws, so no code after it is reachable.
2. Some switch statements are exhaustive, so no code after them are reachable.
PR Close#40984
Currently, when importing `BrowserAnimationsModule`, Angular uses `AnimationRenderer`
as the renderer. When the root view is removed, the `AnimationRenderer` defers the actual
work to the `TransitionAnimationEngine` to do this, and the `TransitionAnimationEngine`
doesn't actually remove the DOM node, but just calls `markElementAsRemoved()`.
The actual DOM node is not removed until `TransitionAnimationEngine` "flushes".
Unfortunately, though, that "flush" will never happen, since the root view is being
destroyed and there will be no more flushes.
This commit adds `flush()` call when the root view is being destroyed.
BREAKING CHANGE:
DOM elements are now correctly removed when the root view is removed. It
is possible that tests could be accidentally relying on the old behavior by
trying to find an element that was not removed in a previous test. If
this is the case, the failing tests should be updated to ensure they
have proper setup code which initializes elements they rely on.
PR Close#41001
Now the language service always uses the name of the JavaScript property on the
component or directive instance for this input or output. This PR will use the right
binding property name.
PR Close#41005
Ngcc uses the `paths` property to compute the potential base-paths
for packages that are being processed. If the `paths` contain a wildcard
`*` within a path segment, ngcc was not finding the base-path correctly.
Now when a wildcard is found, there is an additional search to look for
paths that might match the wildcard.
Fixes#41014
PR Close#41033
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.
This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.
PR Close#40991
This change fixes an incompatibility between the old `@angular/http` package
and its successor (`@angular/common/http`) by re-introducing the types that were supported before.
It now allows to use number and boolean directly as HTTP params, instead of having to convert it to string first.
Before:
this.http.get('/api/config', { params: { page: `${page}` } });
After:
this.http.get('/api/config', { params: { page }});
`HttpParams` has also been updated to have most of its methods accept number or boolean values.
Fixes#23856
BREAKING CHANGE:
The methods of the `HttpParams` class now accept `string | number | boolean`
instead of `string` for the value of a parameter.
If you extended this class in your application,
you'll have to update the signatures of your methods to reflect these changes.
PR Close#40663
Previously, when `ngcc` encountered an entry-point with a format-path
that pointed to a non-existing or empty file it would throw an error and
stop processing the remaining tasks.
In the past, we used to ignore such format-paths and continue processing
the rest of the tasks ([see code][1]). This was changed to a hard
failure in 2954d1b5ca. Looking at the code
history, the reason for changing the behavior was an (incorrect)
assumption that the condition could not fail. This assumption failed to
take into account the case where a 3rd-party library has an invalid
format-path in its `package.json`. This is an issue with the library,
but it should not prevent `ngcc` from processing other
packages/entry-points/formats.
This commit fixes this by reporting the task as failed but not throwing
an error, thus allowing `ngcc` to continue processing other tasks.
[1]: https://github.com/angular/angular/blob/3077c9a1f89c5bd75fb96c16e/packages/compiler-cli/ngcc/src/main.ts#L124Fixes#40965
PR Close#40985
This commit adds more configurability to the `Router#isActive` method
and `RouterLinkActive#routerLinkActiveOptions`.
It allows tuning individual match options for query params and the url
tree, which were either both partial or both exact matches in the past.
Additionally, it also allows matching against the fragment and matrix
parameters.
fixes#13205
BREAKING CHANGE:
The type of the `RouterLinkActive.routerLinkActiveOptions` input was
expanded to allow more fine-tuned control. Code that previously read
this property may need to be updated to account for the new type.
PR Close#40303
Currently the only way to disable animations is by providing the `NoopAnimationsModule`
which doesn't allow for it to be disabled based on runtime information. These changes
add support for disabling animations based on runtime information by using
`BrowserAnimationsModule.withConfig({disableAnimations: true})`.
PR Close#40731
Currently there are two entry points for the `@angular/language-service`
package:
- `@angular/language-service`
This default entry point is for View Engine LS. Through the redirection
of `main` field in `package.json`, it resolves to
`./bundles/language-service.js`.
- `@angular/language-service/bundles/ivy.js`
This secondary entry point is for Ivy LS.
TypeScript recently changed the behavior of tsserver to allow only package
names as plugin names [1] for security reasons. This means the secondary
entry point for Ivy LS can no longer be used.
We implemented a quick hack in the module resolver (in the extension repo)
to fix this, but the long term fix should be in `@angular/language-service`.
Here, the `main` field in `package.json` is changed to `index.js`, and in the
index file we conditionally load View Engine or Ivy based on the input config.
This eliminates the need for multiple entry points.
As part of this PR, I also removed all source code for View Engine and Ivy
included in the NPM package. Consumers of this package should run the bundled
output and nothing else. This would help us prevent an accidental import that
results in execution of unbundled code.
[1]: https://github.com/microsoft/TypeScript/pull/42713
PR Close#40967
These tests were relying upon unix-like paths, which
caused them to fail on Windows.
Note that the `filegroup` Bazel rule tends not to work well
on Windows, so this has been replaced with `copy_to_bin`
instead.
PR Close#40952
Some tools (such as Language Server and ng-packagr) only care about
the processed typings generated by ngcc. Forcing these tools to process
the JavaScript files as well has two disadvantages:
First, unnecessary work is being done, which is time consuming.
But more importantly, it is not always possible to know how the final bundling
tools will want the processed JavaScript to be configured. For example,
the CLI would prefer the `--create-ivy-entry-points` option but this would
break non-CLI build tooling.
This commit adds a new option (`--typings-only` on the command line, and
`typingsOnly` via programmatic API) that instructs ngcc to only render changes
to the typings files for the entry-points that it finds, and not to write any
JavaScript files.
In order to process the typings, a JavaScript format will need to be analysed, but
it will not be rendered to disk. When using this option, it is best to offer ngcc a
wide range of possible JavaScript formats to choose from, and it will use the
first format that it finds. Ideally you would configure it to try the `ES2015` FESM
format first, since this will be the most performant.
Fixes#40969
PR Close#40976
This commit updates compiler_spec.ts in the Ivy LS suite to utilize the new
testing environment which was introduced in the previous commit. Eventually
all specs should be converted, but converting one right now helps ensure
that the new testing env is working properly and able to support real tests.
PR Close#40966
With this change we drop support for zone.js 0.10.x.
This is needed because in version 12 the CLI will only work with `~0.11.4`. See angular/angular-cli#20034.
BREAKING CHANGE:
Minimum supported `zone.js` version is `0.11.4`
PR Close#40823
The Angular LS does not provide quick info when the given position is not
inside a template. As an optimization, we can quickly look at the
file and determine if we are at a position that is part of an Angular
template. If not, we bail before asking the compiler for any more
information. Note that the Angular LS _already_ provides no quick info
when outside a template file, but currently asks the compiler to analyze
the program before it determines that information.
PR Close#40956
Currently `NgTemplateOutlet` recreates its view if its template is swapped out or a context
object with a different shape is passed in. If an object with the same shape is passed in,
we preserve the old view and we mutate the previous object. This mutation of the original
object can be undesirable if two objects with the same shape are swapped between two
different template outlets.
The current behavior is a result of a limitation in `core` where the `context` of an embedded
view is read-only, however a previous commit made it writeable.
These changes resolve the context mutation issue and clean up a bunch of unnecessary
logic from `NgTemplateOutlet` by taking advantage of the earlier change.
Fixes#24515.
PR Close#40360
Currently `EmbeddedViewRef.context` is read-only which means that the only way to update
it is to mutate the object which can lead to some undesirable outcomes if the template
and the context are provided by an external consumer (see #24515).
These changes make the property writeable since there doesn't appear to be a specific
reason why it was readonly to begin with.
PR Close#40360
This commit moves a constant which is affected by a g3 sync patch into a
separate file. This way, changes to the rest of the compiler codebase have
no chance of conflicting with the patched code.
PR Close#40950
When certain information is requested from the Angular Language Service, we
know that there will be no additional Angular information if the requested
position is not in an inline template, template url, or style url. To avoid
unnecessary compiler compilations, we short circuit and return `undefined`
before asking the compiler for any type of answer which would trigger a
partial compilation, at the very least.
fixes https://github.com/angular/vscode-ng-language-service/issues/1104
PR Close#40946
fix https://github.com/angular/components/issues/21674
When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
the reason is before this commit, the code looks like this:
```
// application code call `ngZone.run()`
ngzone.run(() => {}); // step 1
// inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()
function delayChangeDetectionForEvents(zone: NgZonePrivate) {
if (zone.lastRequestAnimationFrameId !== -1) { // step 9
return;
}
zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
if (!zone.fakeTopEventTask) {
zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
zone.lastRequestAnimationFrameId = -1; // step 3
updateMicroTaskStatus(zone); // step 4
checkStable(zone); // step 6
}, undefined, () => {}, () => {});
}
zone.fakeTopEventTask.invoke();
});
updatemicroTaskStatus(zone);
}
function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
if (zone._hasPendingMicrotasks ||
((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
zone.lastRequestAnimationFrameId !== -1)) { // step 5
zone.hasPendingMicrotasks = true;
} else {
zone.hasPendingMicrotasks = false;
}
}
function checkStable(zone: NgZonePrivate) {
if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
try {
zone._nesting++;
zone.onMicrotaskEmpty.emit(null);
...
}
// application ref subscribe onMicroTaskEmpty
ngzone.onMicroTaskEmpty.subscribe(() => {
ngzone.run(() => { // step 8
tick();
});
});
```
and the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. and become a infinite loop..., so onStable is never emit
in this commit, there is a new flag `zone.isCheckStableRunning` added to
prevent re-entry when `shouldCoaleascing` flag is enabled.
PR Close#40540
Currently TestBed (both ViewEngine and Ivy) invoke `ApplicationInitStatus.runInitializers` as a part of the
bootstrap process to mimic real bootstrap steps. This is problematic for the `ApplicationInitStatus` class
tests since the `runInitializers` call performed by TestBed interfere with actual tests.
This commit updates ApplicationInitStatus tests to interact with the class directly instead of relying on TestBed
APIs to retrieve the class though DI.
PR Close#33222
This commit adds support for Observables that now can be used as a part of APP_INITIALIZER. Previously, only
Primises were supported.
Closes#15088.
PR Close#33222
This commit updates compiler_spec.ts in the Ivy LS suite to utilize the new
testing environment which was introduced in the previous commit. Eventually
all specs should be converted, but converting one right now helps ensure
that the new testing env is working properly and able to support real tests.
PR Close#40679
The Ivy Language Service codebase testing suite contains a few testing
utilities which allow for assertions of Language Service operations against
an in-memory project. However, this existing utility lacks the flexibility
to test more complex scenarios, such as those involving multiple TS projects
with dependencies between them.
This commit introduces a new 'testing' package for the Ivy LS which attempts
to more faithfully represent the possible states of an IDE, and allows for
testing of more advanced scenarios. The new utility borrows from the prior
version and is geared towards more ergonomic testing. Only basic
functionality is present in this initial implementation, but this will grow
over time.
PR Close#40679
This PR performs a small refactoring to use `RuntimeError` class and corresponding error code (by calling
`throwProviderNotFoundError` which formats the message) to make it more consistent with other places where
similar errors are thrown.
PR Close#40901
This PR formalizes, documents, and makes public the router outlet contract.
The set of `RouterOutlet` methods used by the `Router` has not changed
in over 4 years, since the introduction of route reuse strategies.
Creation of custom router outlets is already possible and is used by the
Ionic framework
(https://github.com/ionic-team/ionic-framework/blob/master/angular/src/directives/navigation/ion-router-outlet.ts).
There is a small "hack" that is needed to make this work, which is that
outlets must register with `ChildrenOutletContexts`, but it currently
only accepts our `RouterOutlet`.
By exposing the interface the `Router` uses to activate and deactivate
routes through outlets, we allow for developers to more easily and safely
extend the `Router` and have fine-tuned control over navigation and component
activation that fits project requirements.
PR Close#40827
Currently, the function that is provided through `HAMMER_LOADER` is called the
same number of times as the `HammerGesturesPlugin.addEventListener` method is called
(until the Hammer is loaded).
This commit adds a class property in which the loader call is saved, thereby
preventing multiple calls to the loader function.
PR Close#25995
PR Close#40911
Previously we were calling `updateSourceLocations()` as part of
`extractMessages()` for every file that was passed in, regardless of
whether any `$localize` tagged strings were to be found in the file.
This was very wasteful because it is non-trivial to compute the flattened
source-map for files if it is not needed.
PR Close#40891
This is a pre-requisite for #40360. Given the following template which has a listener
that references a variable from a parent template (`name`):
```
<ng-template let-name="name">
<button (click)="hello(name)"></button>
</ng-template>
```
We generate code that looks that looks like. Note how we access `name` through `ctx`:
```js
function template(rf, ctx) {
if (rf & 1) {
const r0 = ɵɵgetCurrentView();
ɵɵelementStart(0, "button", 2);
ɵɵlistener("click", function() {
ɵɵrestoreView(r0);
const name_r0 = ctx.name; // Note the `ctx.name` access here.
const ctx_r1 = ɵɵnextContext();
return ctx_r1.log(name_r0);
});
ɵɵelementEnd();
}
}
```
This works fine at the moment, because the template context object can't be changed after creation.
The changes in #40360 allow for the object to be changed, which means that the `ctx` reference
inside the listener will be out of date, because it was bound during creation mode.
This PR aims to address the issue by accessing the context inside listeners through the saved
view reference. With the new code, the generated code from above will look as follows:
```js
function template(rf, ctx) {
if (rf & 1) {
const r0 = ɵɵgetCurrentView();
ɵɵelementStart(0, "button", 2);
ɵɵlistener("click", function() {
const restoredCtx = ɵɵrestoreView(r0);
const name_r0 = restoredCtx.name;
const ctx_r1 = ɵɵnextContext();
return ctx_r1.log(name_r0);
});
ɵɵelementEnd();
}
}
```
PR Close#40833
This commit adds `ngDevMode` guard to show the warning only
in dev mode (similar to how things work in other parts of Ivy runtime code).
The `ngDevMode` flag helps to tree-shake the warning from production builds
(in dev mode everything will work as it works right now) to decrease production bundle size.
PR Close#40876
Our approach for handling cyclic imports results in code that is
not easy to tree-shake, so it is not suitable for publishing in a
library.
When compiling in partial compilation mode, we are targeting
such library publication, so we now create a fatal diagnostic
error instead of trying to handle the cyclic import situation.
Closes#40678
PR Close#40782
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.
Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
* Prevention of duplicate loading of modules.
related to #26557
* Prevention of duplicate RouteConfigLoad(Start|End) events
related to #22842
* Ensuring preload strategy remains active for submodules if needed
The selected preload strategy should still decide when to load submodules
* Possibility of memory leak with unfinished preload subscription
related to #26557
* Ensure that the stored loader promise is cleared so that subsequent
load will try the fetch again.
* Add error handle error from loadChildren
* Ensure we handle error from with NgModule create
Fixes#26557#22842#26557
PR Close#40389
This commit adds the `emitEvent` option to the following FormArray and FormGroup methods:
* FormGroup.addControl
* FormGroup.removeControl
* FormGroup.setControl
* FormArray.push
* FormArray.insert
* FormArray.removeAt
* FormArray.setControl
* FormArray.clear
This option can be used to prevent an event from being emitted when adding or removing controls.
BREAKING CHANGE:
The `emitEvent` option was added to the following `FormArray` and `FormGroup` methods:
* FormGroup.addControl
* FormGroup.removeControl
* FormGroup.setControl
* FormArray.push
* FormArray.insert
* FormArray.removeAt
* FormArray.setControl
* FormArray.clear
If your app has custom classes that extend `FormArray` or `FormGroup` classes and override the
above-mentioned methods, you may need to update your implementation to take the new options into
account and make sure that overrides are compatible from a types perspective.
Closes#29662.
PR Close#31031
The previous commits refactored the `ShadowCss` emulator to support
desirable use-cases of `:host-context()`, but it dropped support
for passing a comma separated list of selectors to the `:host-context()` .
This commit rectifies that omission, despite the use-case not being
valid according to the ShadowDOM spec, to ensure backward compatibility
with the previous implementation.
PR Close#40494
In `ViewEncapsulation.Emulated` mode the compiler converts `:host` and
`:host-context` pseudo classes into new CSS selectors.
Previously, when there was both `:host-context` and `:host` classes in a
selector, the compiler was generating incorrect selectors. There are two
scenarios:
* Both classes are on the same element (i.e. not separated). E.g.
`:host-context(.foo):host(.bar)`. This setup should only match the
host element if it has both `foo` and `bar` classes. So the generated
CSS selector should be: `.foo.bar<hostmarker>`.
* The `:host` class is on a descendant of the `:host-context`. E.g.
`:host-context(.foo) :host(.bar)`. This setup should only match the
`.foo` selector if it is a proper ancestor of the host (and not on the
host itself). So the generated CSS selector should be:
`.foo .bar<hostmarker>`.
This commit fixes the generation to handle these scenarios.
Fixes#14349
PR Close#40494
In `ViewEncapsulation.Emulated` mode, the compiler must generate additional
combinations of selectors to handle the `:host-context()` pseudo-class function.
Previously, when there is was more than one `:host-context()` selector in a
rule, the compiler was generating invalid selectors.
This commit generates all possible combinations of selectors needed to
match the same elements as the native `:host-context()` selector.
Fixes#19199
PR Close#40494
In Chrome 83 passing a TrustedScript to eval just returns the
TrustedScript back without evaluating it, causing the
newTrustedFunctionFor{Dev,JIT} functions to fail. This is a browser bug
that has been fixed in Chrome 84, and only affects Angular applications
running with JIT (which includes unit tests).
As a temporary workaround for users still on Chrome 83, detect when this
occurs in the newTrustedFunctionFor* functions and fall back to the
straightforward, non-Trusted Types compatible implementation. The only
combination that is left affected consists of Angular applications
running with JIT, that have explicitly configured Trusted Types in
enforcement mode, with users that are still on Chrome 83.
Also correct docstring for newTrustedFunctionForJIT.
PR Close#40815
This commit implements creating of `ɵɵngDeclarePipe()` calls in partial
compilation, and processing of those calls in the linker and JIT compiler.
See #40677
PR Close#40803
`@angular/platform-server` provides the foundation for rendering an
Angular app on the server. In order to achieve that, it uses a
server-side DOM implementation (currently [domino][1]).
For rendering on the server to work as closely as possible to running
the app on the browser, we need to make DOM globals (such as `Element`,
`HTMLElement`, etc.), which are normally provided by the browser,
available as globals on the server as well.
Currently, `@angular/platform-server` achieves this by extending the
`global` object with the DOM implementation provided by `domino`. This
assignment happens in the [setDomTypes()][2] function, which is
[called in a `PLATFORM_INITIALIZER`][3]. While this works in most cases,
there are some scenarios where the DOM globals are needed sooner (i.e.
before initializing the platform). See, for example, #24551 and #39950
for more details on such issues.
This commit provides a way to solve this problem by exposing a
side-effect-ful entry-point (`@angular/platform-server/init`), that
shims the `global` object with DOM globals. People will be able to
import this entry-point in their server-rendered apps before
bootstrapping the app (for example, in their `main.server.ts` file).
(See also [#39950 (comment)][4].)
In a future update, the [`universal` schematics][5] will include such an
import by default in newly generated projects.
[1]: https://www.npmjs.com/package/domino
[2]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/domino_adapter.ts#L17-L21
[3]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/server.ts#L33
[4]: https://github.com/angular/angular/issues/39950#issuecomment-747598403
[5]: https://github.com/angular/angular-cli/blob/cc51432661eb4ab4b6a3/packages/schematics/angular/universal
PR Close#40559
The `platform-server` package currently depends on the [domino][1]
package. This commit adds `domino` to the list of dependencies for the
`platform-server` `ng_module` target.
[1]: https://www.npmjs.com/package/domino
PR Close#40559
This commit causes imports added by ngtsc's `ImportManager` to have their
TypeScript "original node" set to the generated `ts.ImportDeclaration`
statement.
In g3, the tsickle transformer runs after the Angular transformer and post-
processes Angular's compilation output. One of its post-processing tasks is
to transform generated imports and references to imported symbols from the
commonjs module system to the g3 module system. Part of this transformation
involves recognizing modules with specific metadata and altering references
to symbols from those modules accordingly.
Normally, tsickle can rely on TypeScript's binding for an imported symbol to
find its origin module and thus the correct metadata for the symbol. However
the Angular transform generates new synthetic imports which don't have such
binding information. Angular's imports are always namespace imports of the
form:
```
import * as qualifier 'module/specifier';
```
References to such an import are then of the form `qualifier.SymbolName`.
To process such imports properly, tsickle needs to be able to associate the
reference to `qualifier` in the expression `qualifer.SymbolName` with the
`ts.ImportDeclaration` statement that defines it. It expects to do this by
looking at the `ts.getOriginalNode()` for the `qualifier` reference, which
should be the `ts.ImportDeclaration`. This commit changes ngtsc's import
generation mechanism to set the original node on `qualifier` identifiers
according to this expectation.
This commit is not tested in the direct compiler tests, since:
1) there is no observable behavior externally from setting the original node
2) we don't have tests that intercept transformer operations (which could be
used to directly assert against the AST nodes)
3) tsickle's published version does not (yet) contain the g3-specific
transformations which rely on the original node and would thus allow the
behavior to be observed.
Instead, we rely on the g3 testing suite to validate the correctness of this
fix. Breaking this functionality would cause g3 compilation errors for
targets, since tsickle would be unable to transform imports correctly.
PR Close#40711
Fix router to ensure that a route module is only loaded once especially
in relation to the use of preload strategies with delayed or partial
loading.
Add test to check the interaction of PreloadingStrategy and normal
router navigation under differing scenarios.
Checking:
* Prevention of duplicate loading of modules.
related to #26557
* Prevention of duplicate RouteConfigLoad(Start|End) events
related to #22842
* Ensuring preload strategy remains active for submodules if needed
The selected preload strategy should still decide when to load submodules
* Possibility of memory leak with unfinished preload subscription
related to #26557
* Ensure that the stored loader promise is cleared so that subsequent
load will try the fetch again.
* Add error handle error from loadChildren
* Ensure we handle error from with NgModule create
Fixes#26557#22842#26557
PR Close#40389
This commit adds support for Finnish full date formatting,
as well as `c/cc/ccc/cccc/ccccc/cccccc` date formats in the `DatePipe`.
Fixes#26922
PR Close#40766
Before this change, when Google Chrome cancels a XMLHttpRequest, an Observable of the response
never finishes. This happens, for example, when you put your computer to sleep or just press
Ctrl+S to save the browser page. After this commit, if request is canceled or aborted an
appropriate Observable will be completed with an error.
Fixes#22324
PR Close#40767
The parser does not include parenthesis in the AST, so if a LHS
expression would be parenthesized then its start span would start
after the opening parenthesis. Previously, some parent AST nodes would
be created with the start span of its LHS as its own start, so this
resulted in the parent AST node not encompassing the opening parenthesis
in its source span. This commit fixes the issue by capturing the start
index prior to parsing a child AST tree, which is then used as the
start of the source span of the the parent AST node that is parsed.
Fixes#40721
PR Close#40740
In 5c547675b11a24b16c20df1718583a0e7ed49cbd the `EventEmitter.subscribe`
API was extended with a new signature that allows the emitter's generic
type `T` to flow into the subscribe callback. This new signature removes
the need for the special `_outputHelper` function that used to be
emitted into TCBs when `strictOutputEventTypes`/`strictTemplates` is
enabled.
PR Close#40738
Adds an error if a reference is used more than once on the same element (e.g. `<div #a #a>`).
We used to have this error in ViewEngine, but it wasn't ported over to Ivy.
Fixes#40536.
PR Close#40538
This commit fixes the issue of the ASSERTION ERROR issue when
a projected node(RNode) inside an array is checked against the types
of TNodeType.Element, TNodeType.Container, TNodeType.ElementContainer,
TNodeType.IcuContainer, TNodeType.Projection. As it's inside an array,
it doesn't fall into any of those types, as a result, it throws
the ASSERTION ERROR.
PR Close#37120
PR Close#37167
Produces a diagnostic when we cannot resolve a component's external style sheet or external template.
The previous behavior was to throw an exception, which crashed the
Language Service.
fixes angular/vscode-ng-language-service#1079
PR Close#40660
When using the [timeout attribute](https://xhr.spec.whatwg.org/#the-timeout-attribute) and an XHR
request times out, browsers trigger the `timeout` event (and execute the XHR's `ontimeout`
callback). Additionally, Safari 9 handles timed-out requests in the same way, even if no `timeout`
has been explicitly set on the XHR.
In the above cases, `HttpClient` would fail to capture the XHR's completing (with an error), so
the corresponding `Observable` would never complete.
PR Close#26453
PR Close#39807
When the downleveling helper function has been inlined into the
`$localize` call, it is a bit more tricky to parse out the cooked and
raw strings. There was already code to do this but it assumed that
the `cooked` and `raw` items were both arrays.
Sometimes the `raw` array is just a copy of the `cooked` array
via an expression similar to `raw || (raw=tcookedslice(0))`. This
commit changes the `unwrapMessagePartsFromLocalizeCall()`
function to be able to handle such a situation.
Fixes#40702
PR Close#40754
Previously if the code is invalid the error message might look like:
```
Unexpected messageParts for `$localize` (expected an array of strings).
```
This is not very helpful for debugging where the problem occurs.
Now we build a "code-frame" description to give more useful information:
```
TypeError: Cannot create property 'message' on string '.../src/app/app.component.js:
Unexpected messageParts for `$localize` (expected an array of strings).
4 | export class AppComponent {
5 | constructor() {
> 6 | this.title = $localize(a = ['myapp'], []);
| ^^^^^^^^^^^^^
7 | }
8 | }
```
PR Close#40724
Prior to this patch, if an element was removed multiple times (due
to the nature of parent/child elements), the leave listeners may
have been fired for an element that was already removed. This patch
adds a guard within the animations code to prevent this.
PR Close#40712
Close#40387
Currently zone.js patches `setTimeout` and keeps a `tasksByHandleId` map to keep `timerId` <-> `ZoneTask`
relationship. This is needed so that when `clearTimeout(timerId)` is called, zone.js can find the associated
`ZoneTask`. Now zone.js set the `tasksByHandleId` map in the `scheduleTask` function, but if the `setTimeout`
is running in the `FakeAsyncZoneSpec` or any other `ZoneSpec` with `onScheduleTask` hooks. The `scheduleTask`
in `timer` patch may not be invoked.
For example:
```
fakeAsync(() => {
setTimeout(() => {});
tick();
});
```
In this case, the `timerId` kept in the `tasksByHandleId` map is not cleared.
This is because the `FakeAsyncZoneSpec` in the `onScheduleTask` hook looks like this.
```
onScheduleTask(delegate, ..., task) {
fakeAsyncScheduler.setTimeout(task);
return task;
}
```
Because `FakeAsyncZoneSpec` handles the task itself and it doesn't call `parentDelegate.onScheduleTask`,
therefore the default `scheduleTask` in the `timer` patch is not invoked.
In this commit, the cleanup logic is moved from `scheduleTask` to `setTimeout` patch entry to
avoid the memory leak.
PR Close#40586
This commit adds the missing `min` and `max` validators.
BREAKING CHANGE:
Previously `min` and `max` attributes defined on the `<input type="number">`
were ignored by Forms module. Now presence of these attributes would
trigger min/max validation logic (in case `formControl`, `formControlName`
or `ngModel` directives are also present on a given input) and
corresponding form control status would reflect that.
Fixes#16352
PR Close#39063
No longer emits to `Router.events` after the router has been destroyed. Also
returns a resolved promise to the navigation methods.
Fixes#40502.
PR Close#40638
Two motivations behind this change:
1. We would like to expose the types of the Language Service to external
users (like the VSCode extension) via the npm package, on the top
level of the package
2. We would like the View Engine and Ivy LS to share a common interface
(notably after the inclusion of `getTcb`, the Ivy LS upholds a
strict superset of `ts.LanguageService`; previously both VE and Ivy
LS were aligned on `ts.LanguageService`.)
To this end, this commit refactors the exports on the toplevel of the
`language-service/` package to just be types common to both the VE and
Ivy language services. The VE and Ivy build targets then import and use
these types accordingly, and the expectation is that an external user
will just import the relevant typings from the toplevel package without
diving into either the VE or Ivy sources.
Follow up on #40607
PR Close#40621
This commit updates `AbstractControlStatus` directive code to remove duplicated logic in getters and replaces
that logic with a new function that accepts an argument.
PR Close#40651
The `AsyncPipe.transform<T>(emitter)` method must infer the `T`
type from the `emitter` parameter. Since we changed the `AsyncPipe`
to expect a `Subscribable<T>` rather than `Observable<T>` the
`EventEmitter.subscribe()` method needs to have a tighter signature.
Otherwise TypeScript struggles to infer the type and ends up making
it `unknown`.
Fixes#40637
PR Close#40644
The `TemplateTypeChecker.overrideComponentTemplate` operation was originally
conceived as a "fast path" for the Language Service to react to a template
change without needing to go through a full incremental compilation step. It
served this purpose until the previous commit, which switches the LS to use
the new resource-only incremental change operation provided by `NgCompiler`.
`overrideComponentTemplate` is now no longer utilized, and is known to have
several hard-to-overcome issues that prevent it from being useful in any
other situations. As such, this commit removes it entirely.
PR Close#40585
This commit changes the Language Service's "compiler factory" mechanism to
leverage the new resource-only update path for `NgCompiler`. When an
incoming change only affects a resource file like a component template or
stylesheet, going through the new API allows the Language Service to avoid
unnecessary incremental steps of the `NgCompiler` and return answers more
efficiently.
PR Close#40585
Normally the template parsing operation normalizes all template line endings
to '\n' only. This normalization operation causes source mapping errors when
the original template uses '\r\n' line endings.
The compiler already parses templates again to create a "diagnostic"
template AST with accurate source maps, to avoid other parsing issues that
affect source map accuracy. This commit configures this diagnostic parse to
also preserve line endings.
PR Close#40597
In b6cd38ff05 we fixed the DatePipe so
that when it parsed date strings that looked like `YYYY-MM` it created a UTC
date that was not affected by the local timezone of the JavaScript engine.
This commit does the same for date strings of the form `YYYY`.
(Note that the previous commit, mentioned above, attempted to fix this case
too but the test was not actually checking the correct input string.)
Fixes#33944
PR Close#40620
PR Close#40629
In 2aba8b0 we fixed the DatePipe so that when it parsed date strings
that looked like `YYYY-MM-DD` it created a UTC date that was not
affected by the local timezone of the JavaScript engine.
This commit does the same for date strings of the form `YYYY-MM`
and `YYYY`.
Fixes#33944
PR Close#40620
fix https://github.com/angular/components/issues/21674
When setting `ngZoneRunCoalescing` to true, `onStable` is not emitted correctly.
The reason is before this commit, the code looks like this
```
// Application code call `ngZone.run()`
ngZone.run(() => {}); // step 1
// Inside NgZone, in the OnInvoke hook, NgZone try to delay the checkStable()
function delayChangeDetectionForEvents(zone: NgZonePrivate) {
if (zone.lastRequestAnimationFrameId !== -1) { // step 9
return;
}
zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(global, () => { // step 2
if (!zone.fakeTopEventTask) {
zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
zone.lastRequestAnimationFrameId = -1; // step 3
updateMicroTaskStatus(zone); // step 4
checkStable(zone); // step 6
}, undefined, () => {}, () => {});
}
zone.fakeTopEventTask.invoke();
});
updateMicroTaskStatus(zone);
}
function updateMicroTaskStatus(zone: NgZonePrivate, ignoreCheckRAFId = false) {
if (zone._hasPendingMicrotasks ||
((zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) &&
zone.lastRequestAnimationFrameId !== -1)) { // step 5
zone.hasPendingMicrotasks = true;
} else {
zone.hasPendingMicrotasks = false;
}
}
function checkStable(zone: NgZonePrivate) {
if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { // step 7
try {
zone._nesting++;
zone.onMicrotaskEmpty.emit(null);
...
}
// application ref subscribe onMicroTaskEmpty
ngZone.onMicroTaskEmpty.subscribe(() => {
ngZone.run(() => { // step 8
tick();
});
});
```
And the process is:
1. step 1: application call ngZone.run()
2. step 2: NgZone delay the checkStable() call in a requestAnimationFrame, and also set
zone.lastRequestAnimationFrameId
3. step 3: Inside the requestAnimationFrame callback, reset zone.lastRequestAnimationFrameId first
4. step 4: update microTask status
5, step 5: if zone.lastRequestAnimationFrameId is -1, that means no microTask pending.
6. step 6: checkStable and trigger onMicrotaskEmpty emitter.
7. step 7: ApplicationRef subscribed onMicrotaskEmpty, so it will call another `ngZone.run()` to process
tick()
8. step 8: And this new `ngZone.run()` will try to check `zone.lastRequestAnimationFrameId` in `step 9`
when trying to delay the checkStable(), and since the zone.lastRequestAnimationFrameId is already reset
to -1 in step 3, so this ngZone.run() will run into step 2 again.
9. And become a infinite loop..., so onStable is never emit
In this commit, the `zone.lastRequestAnimationFrameId` reset is moved after `checkStable()` call.
PR Close#40540
They aim to improve code readability.
Since they are defined by `const enum` they have zero runtime performance impact
over just using constant literals.
Fixes#23543
PR Close#23548
When parsing interpolations, if we encounter an empty interpolation
(`{{}}`), the current code uses a "pretend" value of `$implicit` for the
name as if the interplotion were really `{{$implicit}}`. This is
problematic because the spans are then incorrect downstream since they
are based off of the `$implicit` text.
This commit changes the interpretation of empty interpolations so that
the text is simply an empty string.
Fixes https://github.com/angular/vscode-ng-language-service/issues/1077
Fixes https://github.com/angular/vscode-ng-language-service/issues/1078
PR Close#40583
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.
This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.
PR Close#40587
If the template parse option `leadingTriviaChars` is configured to
consider whitespace as trivia, any trailing whitespace of an element
would be considered as leading trivia of the subsequent element, such
that its `start` span would start _after_ the whitespace. This means
that the start span cannot be used to mark the end of the current
element, as its trailing whitespace would then be included in its span.
Instead, the full start of the subsequent element should be used.
To harden the tests that for the Ivy parser, the test utility `parseR3`
has been adjusted to use the same configuration for `leadingTriviaChars`
as would be the case in its production counterpart `parseTemplate`. This
uncovered another bug in offset handling of the interpolation parser,
where the absolute offset was computed from the start source span
(which excludes leading trivia) whereas the interpolation expression
would include the leading trivia. As such, the absolute offset now also
uses the full start span.
Fixes#39148
PR Close#40513
This commit adds a new `IncrementalResourceCompilationTicket` which reuses
an existing `NgCompiler` instance and updates it to optimally process
template-only and style-only changes. Performing this update involves both
instructing `DecoratorHandler`s to react to the resource changes, as well as
invalidating `TemplateTypeChecker` state for the component(s) in question.
That way, querying the `TemplateTypeChecker` will trigger new TCB generation
for the changed template(s).
PR Close#40561
To prepare for the optimization of template-only changes, this commit
refactors the `ComponentDecoratorHandler`'s handling of template parsing.
Previously, templates were extracted from the raw decorator metadata and
parsed in a single operation.
To better handle incremental template updates, this commit splits this
operation into a "declaration" step where the template info is extracted
from the decorator metadata, and a "parsing" step where the declared
template is read and parsed. This allows for re-reading and re-parsing of
the declared template at a future point, using the same template declaration
extracted from the decorator.
PR Close#40561
Previously, the incremental flow for NgCompiler was simple: when creating a
new NgCompiler instance, the consumer could pass state from a previous
compilation, which would cause the new compilation to be performed
incrementally. "Local" information about TypeScript files which had not
changed would be passed from the old compilation to the new and reused,
while "global" information would always be recalculated.
However, this flow could be made more efficient in certain cases, such as
when no TypeScript files are changed in a new compilation. In this case,
_all_ information extracted during the first compilation is reusable. Doing
this involves reusing the previous `NgCompiler` instance (the container for
such global information) and updating it, instead of creating a new one for
the next compilation. This approach works cleanly, but complicates the
lifecycle of `NgCompiler`.
To prevent consumers from having to deal with the mechanics of reuse vs
incremental steps of `NgCompiler`, a new `CompilationTicket` mechanism is
added in this commit. Consumers obtain a `CompilationTicket` via one of
several code paths depending on the nature of the incoming compilation, and
use the `CompilationTicket` to obtain an `NgCompiler` instance. This
instance may be a fresh compilation, a new `NgCompiler` for an incremental
compilation, or an existing `NgCompiler` that's been updated to optimally
process a resource-only change. Consumers can use the new `NgCompiler`
without knowledge of its provenance.
PR Close#40561
The Language Service uses the source span of AST nodes to recognize which
node a user has selected, given their cursor position in a template. This is
used to trigger autocompletion.
The previous source span of BindingPipe nodes created a problem when:
1) the pipe binding had no identifier (incomplete or in-progress expression)
2) the user typed trailing whitespace after the pipe character ('|')
For example, the expression `{{foo | }}`. If the cursor preceded the '}' in
that expression, the Language Service was unable to detect that the user was
autocompleting the BindingPipe expression, since the span of the BindingPipe
ended after the '|'.
This commit changes the expression parser to expand the span of BindingPipe
expressions with a missing identifier, to include any trailing whitespace.
This allows the Language Service to correctly recognize this case as
targeting the BindingPipe and complete it successfully. The `nameSpan` of
the BindingPipe is also moved to be right-aligned with the end of any
whitespace present in the pipe binding expression.
This change allows for the disabled test in the Language Service for pipe
completion in this case to be re-enabled.
PR Close#40346
The `LanguageServiceAdapter` must implement `realpath` in order to resolve
symlinks in `node_modules`.
Local libraries are often symlinked in `node_modules` by adding a local
dependency in `package.json`.
Fix https://github.com/angular/vscode-ng-language-service/issues/1083
PR Close#40593
Previously, in `_mismatch()`, the `DefaultIterableDiffer` first checks
`_linkedRecords` for `itemTrackBy`, then checks `_unlinkedRecords`.
This cause the `DefaultIterableDiffer` to move "later" items that match the
`itemTrackBy` from the old collection, rather than using the "earlier" one.
Now we check `_unlinkedRecords` first, so that the `DefaultIterableDiffer`
can give a more stable and reasonable result after diffing. For example,
rather than (`a1` and `a2` have same trackById)
```
a1 b c a2 => b a2 c a1
```
we get
```
a1 b c a2 => b a1 c a2
```
where a1 and a2 retain their original order despite both
having the same track by value.
Fixes#23815
PR Close#23941
Updates to rules_nodejs@2.3.3 to take advantage of windows specific fixes.
rules_nodejs@2.3.3 was created as a patch specifically with a fix for
the issues we found updating to rules_nodejs@2.2.2.
PR Close#40581
Update to the latest version of bazel.
`4.0.0` introduced a breaking change on unnecessary backslashes and these
instance are corrected in this change.
PR Close#40579
This is a follow up fix for
894286dd0c.
It turns out that comments can be closed in several ways:
- `<!-->`
- `<!-- -->`
- `<!-- --!>`
All of the above are valid ways to close comment per:
https://html.spec.whatwg.org/multipage/syntax.html#comments
The new fix surrounds `<` and `>` with zero width space so that it
renders in the same way, but it prevents the comment to be closed eagerly.
PR Close#40525
Previously, we were naïvely checking whether a function name was a partial linker
declaration call by testing the map of linkers with `linkers[name]`. Since
`linkers` was a plain object, it also matched function names like `toString`!
This has been refactored as a `Map` to avoid the problem.
PR Close#40563
This PR adds a way for the language server to retrieve compiler options
diagnostics via `languageService.getCompilerOptionsDiagnostics()`.
This will be used by the language server to show a prompt in the editor if
users don't have `strict` or `fullTemplateTypeCheck` turned on.
Ref https://github.com/angular/vscode-ng-language-service/issues/1053
PR Close#40423
Prior to this commit, the `patchValue()` of the `FormGroup` and `FormArray` classes used to throw an exception
when the `value` argument contained a data structure that has `null` or `undefined` as a value for a field
that represents an instance of `FormGroup` or `FormArray` (for `FormControl` it's not a problem, since it
doesn't have nested controls), since the `patchValue()` method tried to iterate over provided values to
match current data structure.
This commit updates the `patchValue()` logic in `FormGroup` and `FormArray` classes to just ignore `null` and
`undefined` values (without any changes to corresponding `FormGroup` and `FormArray` instances). This
behavior looks inline with the `patchValue()` method goal of "doing its best to match the values to the
correct controls" (quote from docs).
Fixes#36672.
Fixes#21021.
PR Close#40534
PR #39235 introduced additional cleanup logic for form controls and directives. The cleanup logic relies
on the presence of ControlValueAccessor instances on FormControlName and FormControl directives. In general
these fields are present and there are also checks to make sure that the mentioned directive instances are
created with CVAs. However some scenarios (primarily tests) may invoke the logic in a way that the directive
instance would not be fully initialized, thus causing CVA to be absent. As a result, the cleanup logic fails
while trying to call some methods on associated CVA instances.
This commit updates the cleanup logic to take into account the situation when CVA is not present.
Fixes#40521.
PR Close#40526
The ARB format doesn't have a dedicated field for message meaning so these changes include it
as a customize attribute called `x-meaning`.
Fixes#40506.
PR Close#40546
The compliance test runner has various macros that process the
expectation files before actually checking their contents. Among those
macros are i18n helpers, which uses a global message counter to be able
to uniquely identify ICU variables.
Because of the global nature of this message index, it was susceptible
to ordering issues which could result in flaky tests, although it failed
very infrequently.
This commit resets the global message counter before applying the macros.
As a result of this change an expectation file had to be updated; this
is actually a bug fix as said test used to fail if run in isolation (if
`focusTest: true` was set for that particular testcase).
PR Close#40529
When migrating zone.js from gulp to bazel, some legacy build config files are still there,
we have `rollup-es5.config.js` and `rollup-es5_global-es2015.config.js`, since in gulp build
system, build `es5` or `esm` files are set in the config file, but in the bazel world,
the output format is not config in the config.js file, but is required by the downstream
bazel target. So we don't really need the two rollup config files any longer.
Another difference is in `rollup-es5.config.js`, the `external` and `global` libraries names
are also config there, and these settings are also valid for `es2015` build, these settings
are not in the `es2015.config.js` for some legacy reasons. So we don't need to keep this
difference either.
PR Close#40481
This commit reverts commit [_fix(service-worker): handle error with
ErrorHandler_](https://github.com/angular/angular/pull/39990/commits/552419d).
With Angular v11.0.4 and commit [_fix(service-worker): handle error with
ErrorHandler_](https://github.com/angular/angular/pull/39990/commits/552419d)
Angular start to send all service worker registration errors to the Angular
standard `ErrorHandler#handleError()` interface, instead of logging them in the
console.
But users existing `ErrorHandler#handleError()` implementations are not adapted
to service worker registration errors and it might result in broken apps or
bad UI.
Passing to `ErrorHandler` is desirable for some and undesirable for others and
the same is true for passing to `console.error()`.
But `console.error()` was used for a long time and thus it is preferable to keep
it as long as a good solution is not found with `ErrorHandler`.
Right now it's hard to define a good solution for `ErrorHandler` because:
1. Given the nature of the SW registration errors (usually outside the control
of the developer, different error messages on each browser/version, often
quite generic error messages, etc.), passing them to the `ErrorHandler` is
not particularly helpful.
2. While `ErrorHandler#handleError()` accepts an argument of type `any` (so
theoretically we could pass any object without changing the public API), most
apps expect an `Error` instance, so many apps could break if we changed the
shape.
3. Ideally, the Angular community want to re-think the `ErrorHandler` API
and add support for being able to pass additional metadata for each error
(such as the source of the error or some identifier, etc.). This change,
however, could potentially affect many apps out there, so the community must
put some thought into it and design it in a way that accounts for the needs
of all packages (not just the SW).
4. Given that we want to more holistically revisit the `ErrorHandler` API, any
changes we make in the short term to address the issue just for the SW will
make it more difficult/breaky for people to move to a new API in the future.
To see the whole explanation see GitHub PR #40236.
PR Close#40236
This is a follow up fix for
894286dd0c.
It turns out that comments can be closed in several ways:
- `<!-->`
- `<!-- -->`
- `<!-- --!>`
All of the above are valid ways to close comment per:
https://html.spec.whatwg.org/multipage/syntax.html#comments
The new fix surrounds `<` and `>` with zero width space so that it
renders in the same way, but it prevents the comment to be closed eagerly.
PR Close#40525
In `ViewEncapsulation.Emulated` mode, the compiler must generate additional
combinations of selectors to handle the `:host-context()` pseudo-class function.
Previously, when there is was more than one `:host-context()` selector in a
rule, the compiler was generating invalid selectors.
This commit generates all possible combinations of selectors needed to
match the same elements as the native `:host-context()` selector.
Fixes#19199
PR Close#40494
When a source-map has an inline source, any source-map linked from
that source should only be loaded if itself is also inline; it should not
attempt to load a source-map from the file-system. Otherwise we can
find ourselves with inadvertent infinite cyclic dependencies.
For example, if a transpiler takes a file (e.g. index.js) and generates
a new file overwriting the original file - capturing the original
source inline in the new source-map (index.js.map) - the source
file loader might read the inline original file (also index.js) and
then try to load the `index.js.map` file from disk - ad infinitum.
Note that the first call to `loadSourceFile()` is special, since you can
pass in the source-file and source-map contents directly as in-memory
strrngs. This is common if the transpiler has just generated these and has
not yet written them to disk.
When the contents are passed into `loadSourceFile()` directly, they are
not treated as "inline" for the purposes described above since there is
no chance of these "in-memory" source and source-map contents being caught
up in a cyclic dependency.
Fixes#40408
PR Close#40435
This patch adds an API to retrieve the template typecheck block for a
template (if any) at a file location, and a selection of the TS node
in the TCB corresponding to the template node at which the request for
a TCB was made (if any).
Probably not something we want to land soon, but a useful debugging tool
for folks working with TCBs.
PR Close#39974
rxjs was only used within one location within the static queries migration to workaround
a previous limitation that schematics could not directly use a promise. However, promise
support has been available since 8.0. This change removes the observable promise wrapping.
It also removes an any cast that was previously needed to workaround rxjs version mismatches
during compilation.
PR Close#38657
Adds an `appendAll()` method to `HttpParams` that can construct the HTTP
request/response body from an object of parameters and values.
This avoids calling `append()` multiple times when multiple parameters
need to be added.
Fixes#20798
PR Close#20930
For the Google Cloud Console within Google we observed errors in the
shallowEqual function for users in IE and Edge. This patch was made within
Google and the errors went away. This commit upstreams the change into Angular.
PR Close#40488
This commits adds additional expectations to verify that the bloom
filter is able to correctly handle token IDs that exceed the size of
the bloom filter (which is currently 256 bits).
PR Close#40489
The injector system uses a bloom filter to determine if a token is
possibly defined in the node injector tree, which is stored across
multiple bloom buckets that each represent 32 bits of the full 256-bit
wide bloom hash. This means that a computation is required to determine
the exact bloom bucket which is responsible for storing any given 32-bit
interval, which was previously computed using three bitmask operations
and three branches to derive the bloom bucket offset.
This commit exploits the observation that all bits beyond the low 5 bits
of the bloom hash are an accurate representation for the bucket offset,
if shifted right such that those bits become the least significant bits.
This reduces the three bitmask operations and three branches with a
single shift operation, while additionally offering a code size
improvement.
PR Close#40489
Rather than mutating the span on the template when renaming literal strings,
this commit updates the logic to mutate the `TextSpan` equivalent that
is used by the Language Service.
PR Close#40484
Fix a case where matrix parameters weren't stringified when they are passed as a first command
when creating a url tree. Fix return type in parseMatrixParams method
because it always returns {[key: string]: string}
Closes#23165
PR Close#25095
Many `ts.LanguageService` APIs accept a filename, for example
```ts
getQuickInfoAtPosition(fileName: string, position: number)
```
The requirement is that `fileName` is agnostic to the platform (Linux, Mac,
Windows, etc), and is always normalized to TypeScript's internal
`NormalizedPath`.
This is evident from the way these APIs are called from the language server:
```ts
private onHover(params: lsp.TextDocumentPositionParams) {
const lsInfo = this.getLSAndScriptInfo(params.textDocument);
if (lsInfo === undefined) {
return;
}
const {languageService, scriptInfo} = lsInfo;
const offset = lspPositionToTsPosition(scriptInfo, params.position);
const info = languageService.getQuickInfoAtPosition(scriptInfo.fileName, offset);
// ...
}
```
9fca9c6651/server/src/session.ts (L594)
Here `scriptInfo.fileName` is always a `ts.server.NormalizedPath`.
However, https://github.com/angular/angular/pull/39917 accidentally leaked
the platform-specific paths, and caused a mismatch between the incoming paths
and the paths stored in the internal data structure `fileToComponent`.
This PR fixes the bug by always normalizing the paths, and updating the
type to reflect the format of the underlying data.
Fixes https://github.com/angular/vscode-ng-language-service/issues/1063
PR Close#40492
The initial implementation assumed that the consuming editors would
de-duplicate rename locations. In fact, vscode treats overlapping rename
locations as distinct and errors when trying to preview the renames.
This commit updates the language service to de-duplicate exact file+span
matches before returning rename and reference locations.
While vscode _does_ de-duplicate reference results, it still makes sense
to de-duplicate them on our side when possible to make tests more
understandable. If a template has 3 instances of a variable, it makes
sense to get get 3 reference results rather than 4+ with some duplicates.
PR Close#40454
The current "go to definition" is broken for template variables and
references when a template is overridden. This is because we get the
file url from the source span, which uses the overridden name
'override.html'. Instead, we can retrieve the template file from the
compiler in the same manner that is done for references.
Another way to fix this would have been to use the real template file path when
overriding a template, but this was the more straightforward fix since
the strategy was already used in find references and rename locations.
fixes https://github.com/angular/vscode-ng-language-service/issues/1054
PR Close#40455
When a form is reset, it goes through `_forEachChild` to call `reset` on each of its children.
The problem is that if a control is removed while the loop is running (e.g. by a subscription),
the form will throw an error, because it built up the list of available control before the loop
started.
These changes fix the issue by adding a null check before invoing the callback.
Fixes#33401.
PR Close#40462
Close#40215
`fesm2015/zone.js` is built to `esm` bundle with rollup, so the 'use strict';
statement is not generated in the bundle, even we put the 'use strict' in the src code,
rollup removes the code in the final bundle.
So if we load the `fesm2015/zone.js` as a module, such as `ng serve`, in the index.html
```
<script src="polyfills.js" type="module"></script>
```
Everything works fine, since polyfills.js is loaded as `module`, so it is always `strict`.
But in `ng test`, webpack concat the `zone.js` and loaded into the karma html. For other app and
test code, they are still `strict` since they are `module` because they have `export/import`
statement, but `zone.js` is a bundle without `export`, it is a `side effect` bundle, so after
loaded by webpack, it becomes non-strict. Which causes some issues, such as #40215,
the root cause is the `this` context should be `undefined` but treated as `Window` in `non-strict` mode.
```
Object.prototype.toString.apply(undefined);
// should be [object undefined], but it is [object Window] in non-strict mode.
// zone.js patched version of toString
Object.prototype.toString = function() {
...
// in non-strict mode, this is Window
return originalObjectPrototypeToString.call(this);
}
```
So in this commit, `'use strict';` is always added to the `esm` bundles.
PR Close#40456
The `getRenameInfo` action is used by consumers to
1. Determine if a location is a candidate for renames
2. Determine what text to use as the starting point for the rename
PR Close#40439
We should provide the completion when the cursor is in the attribute
name after the `@` and `animate-`, but now the `KeySpan` starts from the
`@` or `animate-`. For example, the animation event `(@name.done)="v"`,
we can know where the cursor is by the `KeySpan` of `name.done` exactly,
it's in the event name or in the phase name.
PR Close#40347
Reasons for change:
- css_parser, css_ast, and css_lexer are not used anywhere and there are
no entry points from compiler.ts
- tested by building Angular and building/running aio with build-local
PR Close#37463
When loading a module that doesn't provide `RouterModule.forChild()` preloader will get stuck
in an infinite loop and throw `ERROR Error: Maximum call stack size exceeded.`
The issue is that child module's `Injector` will look to its parent `Injector` when it doesn't
find any `ROUTES` so it will return routes for it's parent module instead. This will load the
child again that returns its parent's routes and so on.
Closes#29164
PR Close#36605
This commit lays the groundwork for potentially providing rename
locations from the Ivy native LS. The approach is very similar to what
was done with the feature to find references. One difference, however,
is that we did not require the references to be fully "correct". That
is, the exact text spans did not matter so much, as long as we provide a
location that logically includes the referenced item.
An example of a necessary difference between rename locations and references is
directives. The entire element in the template is a "reference" of the
directive's class. However, it's not a valid location to be renamed. The
same goes for aliased inputs/outputs. The locations in the template
directly map to the class property, which is correct for references, but
would not be correct for rename locations, which should instead map to
the string node fo the alias.
As an initial approach to address the aforementioned issues with rename
locations, we check that all the rename location nodes have the same text. If
_any_ node has text that differs from the request, we do not return any
rename locations. This works as a way to prevent renames that could
break the the program by missing some required nodes in the rename action, but
allowing other nodes to be renamed.
PR Close#40140
Because the query now has `flags` which specify the mode, the static query
instruction can now be remove. It is simply normal query with `static` flag.
PR Close#40091
Previous implementation would fire changes `QueryList.changes.subscribe`
whenever the `QueryList` was recomputed. This resulted in artificially
high number of change notifications, as it is possible that recomputing
`QueryList` results in the same list. When the `QueryList` gets recomputed
is an implementation detail and it should not be the thing which determines
how often change event should fire.
This change introduces a new `emitDistinctChangesOnly` option for
`ContentChildren` and `ViewChildren`.
```
export class QueryCompWithStrictChangeEmitParent {
@ContentChildren('foo', {
// This option will become the default in the future
emitDistinctChangesOnly: true,
})
foos!: QueryList<any>;
}
```
PR Close#40091
When using the `NewEntryPointWriter`, we must copy over all files from the
entry-point bundle to the new entry-point. But since we are going to
write out the modified files directly, there is no need to copy those.
This commit skips copying the files that have been modified.
PR Close#40429
When using the `NewEntryPointWriter` we copy unmodified files over to the new
entry-point in addition to writing out the source files that are processed by ngcc.
But we were not copying over associated source-map files for these unmodified
source files, leading to warnings in downstream tooling.
Now we will also copy over source-maps that reside as siblings of unmodified
source files. We have to make sure that the sources of the source-map point
to the correct files, so we also update the `sourceRoot` property of the copied
source-map.
Fixes#40358
PR Close#40429
This commit updates the logic that calculates `useFactory` function arguments to avoid relying on `instanceof`
checks (thus always retaining symbols) and relies on flags that DI decorators contain (as a monkey-patched property).
Another perf benefit is having less megamorphic reads while calculating args for the `useFactory` call: we used to
check whether a token has `ngMetadataName` property 4 times (in worst case), now we have just 1 megamorphic read in
all cases.
Closes#40143.
PR Close#40145
Report non-template diagnotics when calling `getDiagnotics` function of
the language service we only returned template diagnotics. This change
causes it to return all diagnotics, not just diagnostics from the
template type checker.
PR Close#40331
This commit fixes a bug in the **View Engine** implementation of
`getSemanticDiagnostics` and `getDefinitionAndBoundSpan` for node in the
decorator metadata that represents an external URL
(`templateUrl` or `styleUrls`).
The URL could be either relative or absolute, but the latter was not taken
into account.
Fix https://github.com/angular/vscode-ng-language-service/issues/1055
PR Close#40406
The `template` and `isInline` fields were previously stored in a nested
object, which was initially done to accommodate for additional template
information to support accurate source maps for external templates. In
the meantime the source mapping has been accomplished in a different
way, and I feel this flattened structure is simpler and smaller so is
preferable over the nested object. This change also makes the `isInline`
property optional with a default value of `false`.
PR Close#40383
The parser has a list of tag definitions that it uses when parsing the template. Each tag has a
`contentType` which tells the parser what kind of content the tag should contain. The problem is
that the browser has two separate `title` tags (`HTMLTitleElement` and `SVGTitleElement`) and each
of them has to have a different `contentType`, otherwise the parser will throw an error further down
the pipeline.
These changes update the tag definitions so that each tag name can have multiple content types
associated with it and the correct one can be returned based on the element's prefix.
Fixes#31503.
PR Close#40259
Do not warn that navigation was triggered outside Angular zone if the
Router was created outside Angular zone in the first place.
Closes#25837
PR Close#25839
Previously, the SW would wait to become idle before executing scheduled
tasks (including checks for newer app versions). It was considered idle
when it hadn't received any request for at least 5 seconds. As a result,
if the app performed polling (i.e. sent requests to the server) in a
shorter than 5 seconds interval, the SW would never detect and update to
a newer app version.
Related issue: #40207
This commit fixes this by adding a max delay to `IdleScheduler` to
ensure that no scheduled task will remain pending for longer than the
specified max delay.
PR Close#40234
This commit refactors `Driver#deleteAllCaches()` to use `Array#map()`
instead of `Array#reduce()` for running async operations in parallel.
This allows avoiding having to recursively wrap Promises with
`Promise.all()`.
PR Close#40234
Previously, clients were notified about updates sequentially. This
wasn't necessary.
This commit changes the `Driver#notifyClientsAboutUpdate()` method to
notify the clients in parallel (by switching from `Array#reduce()` to
`Array#map()` and `Promise.all()`).
This also aligns the `notifyClientsAboutUpdate()` method with the
`notifyClientsAboutUnrecoverableState()` method.
PR Close#40234
Previously, the `Driver#notifyClientsAboutUnrecoverableState()` method
would not wait for the completion of the promises created to notify the
clients. Theoretically, this could result in the SW instance's getting
destroyed by the browser before all clients have been notified. This is
extremely unlikely to happen in practice, since the async operations are
very quick, but it _is_ theoretically possible.
This commit ensures that the SW instance will remain alive while
notifying the clients by making `notifyClientsAboutUnrecoverableState()`
await the notification promises.
PR Close#40234
The decorator downleveling transform patches `ts.EmitResolver.isReferencedAliasDeclaration`
to prevent elision of value imports that occur only in a type-position, which would
inadvertently install the patch repeatedly for each source file in the program.
This could potentially result in a stack overflow when a very large number of files is
present in the program.
This commit fixes the issue by ensuring that the patch is only applied once.
This is also a slight performance improvement, as `isReferencedAliasDeclaration`
is no longer repeatedly calling into all prior installed patch functions.
Fixes#40276
PR Close#40374
Previously, if there were path-mapped entry-points, where one contaied the
string of another - for example `worker-client` and `worker` - then the
base paths were incorrectly computed resulting in the wrong package path
for the longer entry-point. This was because, when searching for a matching
base path, the strings were tested using `startsWith()`, whereas we should
only match if the path was contained in a directory from a file-system
point of view.
Now we not only check whether the target path "starts with" the base path
but then also whether the target path is actually contained in the base path
using `fs.relative()`.
Fixes#40352Fixes#40357
PR Close#40376
`Object.values` is not supported in IE11 without a polyfill. The quickest,
most straightfoward fix for this is to simply use `Object.keys` instead.
We may want to consider including the polyfill in the CLI in the future
or just wait until IE11 support is dropped before using
`Object.values`.
PR Close#40370
Currently the language service has to force `compileNonExportedClasses` to
`true` to handle inline NgModules in tests, regardless of the value in user's
tsconfig.json.
However, the override is not reinstated after the compiler option changes
(triggered by a change in tsconfig.json).
This commit fixes the bug.
PR Close#40364
This commit documents how to add a helper function which combines all the params
in the router state tree into a single object. It provides a starting point for
developers to reference if they require a more fine-tuned approach.
Fixes#11023
PR Close#40306
In #37182 the in-memory-web-api module was moved into this repo.
Copy the reamde into this repo with the following changes:
* Removed Travis badges
* Updated github links to point to Angular repo
* Removed 'running tests' as it is no longer relevant
Fixes#40190
PR Close#40203
When we attach a `ViewRef` to a `ViewContainerRef`, we save a reference to the container
onto the `ViewRef` so that we can remove it when the ref is destroyed. The problem is
that if the container's `hostView` is destroyed first, the `ViewRef` has no way of knowing
that it should stop referencing the container.
These changes remove the leak by not saving a reference at all. Instead, when a `ViewRef`
is destroyed, we clean it up through the `LContainer` directly. We don't need to worry
about the case where the container is destroyed before the view, because containers
automatically clean up all of their views upon destruction.
Fixes#38648.
PR Close#40219
The `NgControlStatusGroup` directive is shared between template-driven and reactive form modules. In cases when
only reactive forms module is present, the `NgControlStatusGroup` directive is still activated on all `<form>`
elements, but if there is no other reactive directive applied (such as `formGroup`), corresponding `ControlContainer`
token is missing, thus causing exceptions (since `NgControlStatusGroup` directive relies on it to determine the
status). This commit updates the logic to handle the case when no `ControlContainer` is present (effectively making
directive logic a noop in this case).
Alternative approach (more risky) worth considering in the future is to split the `NgControlStatusGroup` into
2 directives with different set of selectors and include them into template-driven and reactive modules separately.
The downside is that these directives might be activated simultaneously on the same element (e.g. `<form>`),
effectively doing the work twice.
Resolves#38391.
PR Close#40344
This class is refactored to extend the new `NodeJSReadonlyFileSystem`
which itself extends `NodeJSPathManipulation`. These new classes allow
consumers to create file-systems that provide a subset of the full file-system.
PR Close#40281
Now that `ReadonlyFileSystem` and `PathManipulation` interfaces are
available, this commit updates the localize package to use these more
focussed interfaces.
PR Close#40281
Now that `ReadonlyFileSystem` and `PathManipulation` interfaces are
available, this commit updates the compiler-cli to use these more
focussed interfaces.
PR Close#40281
This interface now extends `ReadonlyFileSystem` which in turn
extends `PathManipulation`. This means consumers of these
interfaces can be more specific about what is needed, and so
providers do not need to implement unnecessary methods.
PR Close#40281
The "monitoring" workflow has been failing since #40127 was merged,
due to a Saucelabs test failure in Internet Explorer 11. The issue is
with the test's expectation which does not account for Ivy instruction
invocations to use "anonymous" instead of the instruction's function
name. This commit changes the test expectation to also accept
"anonymous", which was already the case for similar expectations.
PR Close#40342
Now when the animation trigger output event is missing its phase value name, the `BoundEvent` will be ignored,
but it's useful for completion in language service.
PR Close#39925
This commit adds special handling to the completion builder by detecting
a two way binding context and ensuring that we filter out any `Input`s
that do not support two way binding.
PR Close#40185
Rather than expecting that a position in a template only targets a
single node, this commit simply adjusts the approach to account for two way
bindings. Specifically, we attempt to get references for each targeted
node and then return the combination of all results, or `undefined` if
none of the target nodes had references.
PR Close#40185
Rather than expecting that a position in a template only targets a
single node, this commit adjusts the approach to account for two way
bindings. In particular, we attempt to get definitions for each targeted
node and then return the combination of all results, or `undefined` if
none of the target nodes had definitions.
PR Close#40185
Adjust the visitor logic of the template target as well as the
consumption of the visitor result to account for two-way bindings.
This sets up downstream consumers for being able to handle the
possibility of a template position that targets both an input and an
output.
PR Close#40185
The current template target implementation only allows a way to
represent the template position as targeting a single node in the
template AST. However, there is at least one case (banana-in-a-box)
where a given template position refers to two template targets.
This commit expands the contexts that the `TemplateTarget` can return to
include support for the banana-in-a-box syntax, which has two logically
targetted AST nodes given a position within the `keySpan` of the
binding.
PR Close#40185
This commit fixes the Template Type Checker's `getSymbolOfNode` so that
it is able to retrieve a symbol for the `BoundEvent` of a two-way
binding. Previously, the implementation would locate the node in the TCB
for the input because it appeared first and shares the same `keySpan` as
the event binding. To fix this, the TCB node search now verifies that
the located node matches the expected name for the output subscription:
either `addEventListener` for a native listener or the class member of the Angular `@Output`
in the case of an Angular output, as would be the case for two-way
bindings.
PR Close#40185
Currently when analyzing the metadata of a directive, we bundle together the bindings from `host`
and the `HostBinding` and `HostListener` together. This can become a problem later on in the
compilation pipeline, because we try to evaluate the value of the binding, causing something like
`@HostBinding('class.foo') public true = 1;` to be treated the same as
`host: {'[class.foo]': 'true'}`.
While looking into the issue, I noticed another one that is closely related: we weren't treating
quoted property names correctly. E.g. `@HostBinding('class.foo') public "foo-bar" = 1;` was being
interpreted as `classProp('foo', ctx.foo - ctx.bar)` due to the same issue where property names
were being evaluated.
These changes resolve both of the issues by treating all `HostBinding` instance as if they're
reading the property from `this`. E.g. the `@HostBinding('class.foo') public true = 1;` from above
is now being treated as `host: {'[class.foo]': 'this.true'}` which further down the pipeline becomes
`classProp('foo', ctx.true)`. This doesn't have any payload size implications for existing code,
because we've always been prefixing implicit property reads with `ctx.`. If the property doesn't
have an identifier that can be read using dotted access, we convert it to a quoted one (e.g.
`classProp('foo', ctx['is-foo']))`.
Fixes#40220.
Fixes#40230.
Fixes#18698.
PR Close#40233
This commit changes the `PartialComponentLinker` to use the original source
of an external template when compiling, if available, to ensure that the
source-mapping of the final linked code is accurate.
If the linker is given a file-system and logger, then it will attempt
to compute the original source of external templates so that the final
linked code references the correct template source.
PR Close#40237
Now, if a source-mapping compliance test fails, the message displays both
the path to the generated file, and more helpfully the path to the expected
file.
PR Close#40237
Previously the names of the source and expectation files were often reused,
which caused potential confusion.
There is now a single source file for
each test-case, which is important when they are being compiled with different
compiler options, since the GOLDEN_PARTIAL file will only contain one copy
per file name.
The names of the expectation files have now been changed so that is clearer
which test-case they are related to.
PR Close#40237
The filename of the source-span is now added to the Babel location
when setting the source-map range in the `BabelAstHost`.
Note that the filename is only added if it is different to the main file
being processed. Otherwise Babel will generate two entries in its
generated source-map.
PR Close#40237
When a source-map/source-file tree has nodes that refer to the same file, the
flattened source-map rendering was those files multiple times, rather than
consolidating them into a single source-map source.
PR Close#40237
When partially compiling a component with an external template, we must
synthesize a new AST node for the string literal that holds the contents of
the external template, since we want to source-map this expression directly
back to the original external template file.
PR Close#40237
`Object.entries` is not supported in IE11 without a polyfill. The quickest,
most straightfoward fix for this is to simply use `Object.keys` instead.
We may want to consider including the polyfill in the CLI in the future
or just wait until IE11 support is dropped before using
`Object.entries`.
PR Close#40340
This commit ensures that the template type checker returns symbols for
all outputs if a template output listener binds to more than one.
PR Close#40144
During route activation, a componentless route will not have a context created
for it, but the logic continues to recurse so that children are still
activated. This can be seen here:
362f45c4bf/packages/router/src/operators/activate_routes.ts (L151-L158)
The current deactivation logic does not currently account for componentless routes.
This commit adjusts the deactivation logic so that if a context cannot
be retrieved for a given route (because it is componentless), we
continue to recurse and deactivate the children using the same
`parentContexts` in the same way that activation does.
Fixes#20694
PR Close#40196
We need a means to preserve typecheck files when a project is reloaded,
otherwise the Ivy compiler will throw an error when it's unable to find
them. This commit implements `getExternalFiles()` called by the langauge
server to achieve this goal.
For more info see https://github.com/angular/vscode-ng-language-service/issues/1030
PR Close#40162
`ts.server.ServerHost.resolvePath()` is different from Angular's
`FileSystem.resolve()` because the signature of the former is
```ts
resolvePath(path: string): string; // ts.server.ServerHost
```
whereas the signature of the latter is
```ts
resolve(...paths: string[]): AbsoluteFsPath; // FileSystem on compiler-cli
```
The current implementation calls `path.join()` to concatenate all the input
paths and pass the result to `ts.server.ServerHost.resolvePath()`, but doing
so results in filenames like
```
/foo/bar/baz/foo/bar/baz/tsconfig.json
```
if both input paths are absolute.
`ts.server.ServerHost` should not be used to implement the
`resolve()` method expected by Angular's `FileSystem`.
We should use Node's `path.resolve()` instead, which will correctly collapse
the absolute paths.
Fix https://github.com/angular/vscode-ng-language-service/issues/1035
PR Close#40242
When resolving references, the Ivy compiler has a few strategies it could use.
For relative path, one of strategies is [`RelativePathStrategy`](
https://github.com/angular/angular/blob/master/packages/compiler-cli/src/
ngtsc/imports/README.md#relativepathstrategy). This strategy
relies on `compilerOptions.rootDir` and `compilerOptions.rootDirs` to perform
the resolution, but language service only passes `rootDirs` to the compiler,
and not `rootDir`.
In reality, `rootDir` is very different from `rootDirs` even though they
sound the same.
According to the official [TS documentation][1],
> `rootDir` specifies the root directory of input files. Only use to control
> the output directory structure with --outDir.
> `rootDirs` is a list of root folders whose combined content represent the
> structure of the project at runtime. See [Module Resolution documentation](
> https://www.typescriptlang.org/docs/handbook/
> module-resolution.html#virtual-directories-with-rootdirs)
> for more details.
For now, we keep the behavior between compiler and language service consistent,
but we will revisit the notion of `rootDir` and how it is used later.
Fixangular/vscode-ng-language-service#1039
[1]: https://www.typescriptlang.org/docs/handbook/compiler-options.html
PR Close#40243
CSS supports escaping in selectors, e.g. writing `.foo:bar` will match an element with the
`foo` class and `bar` pseudo-class, but `.foo\:bar` will match the `foo:bar` class. Our
shimmed shadow DOM encapsulation always assumes that `:` means a pseudo selector
which breaks a selector like `.foo\:bar`.
These changes add some extra logic so that escaped characters in selectors are preserved.
Fixes#31844.
PR Close#40264
In some browsers, notably a mobile version of webkit on iPad, the
result of calling `DOMParser.parseFromString()` returns a document
whose `body` property is null until the next tick of the browser.
Since this is of no use to us for sanitization, we now fall back to the
"inert document" strategy for this case.
Fixes#39834
PR Close#40107
The `ɵɵngDeclareComponent` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareComponent` which invokes the JIT compiler
using the declaration object, such that a compiled component definition
is made available to the Ivy runtime.
PR Close#40127
The `render3` test targets are currently also executed for ViewEngine
builds, even though the `render3` infrastructure only concerns Ivy
infrastructure. This commit tags the test targets as ivy-only to disable
those tests for View Engine.
PR Close#40127
The link to the "speeding-up-ngcc-compilation" URL does not exist,
it was removed shortly after it was added, but the link in the ngcc
error message was not updated.
Fixes#39837
PR Close#40285
Currently we check whether a property binding contains an interpolation using a regex so
that we can throw an error. The problem is that the regex doesn't account for quotes
which means that something like `[prop]="'{{ foo }}'"` will be considered an error, even
though it's not actually an interpolation.
These changes build on top of the logic from #39826 to account for interpolation
characters inside quotes.
Fixes#39601.
PR Close#40267
The trustConstantHtml and trustConstantResourceUrl functions are only
meant to be passed constant strings extracted from Angular application
templates, as passing other strings or variables could introduce XSS
vulnerabilities.
To better protect these APIs, turn them into template tags. This makes
it possible to assert that the associated template literals do not
contain any interpolation, and thus must be constant.
Also add tests for the change to prevent regression.
PR Close#40082
When talking about parameter inheritance, one might think that matrix
parameters can be inherited from the "parent" segment, or the segment
which appears immediately to the left. In reality, when we talk about
a "parent" in the `Router`, we mean the parent `Route` config. This
config may contain more than one segment and matrix parameters must
appear at the end or they do not "belong" to any config.
PR Close#40304
There are two parts to this commit:
1. Revert the changes from #38379. This change had an incomplete view of
how things worked and also diverged the implementations of
`applyRedirects` and `recognize` even more.
2. Apply the fixes from the `recognize` algorithm to ensure that named
outlets with empty path parents can be matched. This change also passes
all the tests that were added in #38379 with the added benefit of being
a more complete fix that stays in-line with the `recognize` algorithm.
This was made possible by using the same approach for `split` by
always creating segments for empty path matches (previously, this was
only done in `applyRedirects` if there was a `redirectTo` value). At the
end of the expansions, we need to squash all empty segments so that
serializing the final `UrlTree` returns the same result as before.
Fixes#39952Fixes#10726Closes#30410
PR Close#40029
The `applyRedirects` and `recognize` algorithms have the same overall goal:
match a `UrlTree` with the application's `Routes` config. There are a
few key functions in these algorithms which can be shared rather than
duplicated between the two. This also makes it easier to see how the two
are similar and where they diverge.
PR Close#40029
This commit updates the `recognize` algorithm to work with named outlets
which have empty path parents. For example, given the following config
```
const routes = [
{
path: '',
children: [
{path: 'a', outlet: 'aux', component: AuxComponent}
]}
];
```
The url `/(aux:a)` should match this config. In order to do so, we need
to allow the children of `UrlSegmentGroup`s to match a `Route` config
for a different outlet (in this example, the `primary`) when it's an
empty path. This should also *only* happen if we were unable to find a
match for the outlet in the level above. That is, the matching strategy
is to find the first `Route` in the list which _matches the given
outlet_. If we are unable to do that, then we allow empty paths from
other outlets to match and try to find some child there whose outlet
matches our segment.
PR Close#40029
To make the tests suite easier to follow, `Recognize#apply` can be made
into a synchronous function rather than one that return an `Observable`.
Also, as a chore, remove as many `any` types as possible.
PR Close#40029
This commit updates the `recognize` algorithm to return `null` when a
segment does not match a given config rather than throwing an error.
This makes the code much easier to follow because the "no match" result
has to be explicitly handled rather than catching the error in very
specific places.
PR Close#40029
When stepping through the `recognize` algorithm, it is much easier to
follow when using a simple `for...of` rather than the helper
`mapChildrenIntoArray` with the passed closure. The only special thing that
`mapChildrenIntoArray` does is ensure the primary route appears first.
This change will have no affect on the result because `processChildren` later calls
`sortActivatedRouteSnapshots`, which does the same thing.
PR Close#40029
Prior to this commit, removing `FormControlDirective` and `FormGroupName` directive instances didn't clear
the callbacks previously registered on FromControl/FormGroup class instances. As a result, these callbacks
were executed even after `FormControlDirective` and `FormGroupName` directive instances were destroyed. That was
also causing memory leaks since these callbacks also retained references to DOM elements.
This commit updates the cleanup logic to take care of properly detaching FormControl/FormGroup/FormArray instances
from the view by removing view-specific callback at destroy time.
Closes#20007, #37431, #39590.
PR Close#39235
DI providers can be defined via `useFactory` function, which may have arguments configured via `deps` array.
The `deps` array may contain DI flags represented by DI decorators (such as `@Self`, `@SkipSelf`, etc). Prior to this
commit, having the `@Host` decorator in `deps` array resulted in runtime error in Ivy. The problem was that the `@Host`
decorator was not taken into account while `useFactory` argument list was constructed, the `@Host` decorator was
treated as a token that should be looked up.
This commit updates the logic which prepares `useFactory` arguments to recognize the `@Host` decorator.
PR Close#40122
The CLI integration can provide code files in a non-deterministic
order, which led to the extracted translation files having
messages in a non-consistent order between extractions.
This commit fixes this by ensuring that serialized messages
are ordered by their location.
Fixes#39262
PR Close#40192
`Route` configs with `redirectTo` as well as `canActivate` are not valid
because the `canActivate` guards will never execute. Redirects are
applied before activation. There is no error currently for these
configs, but another commit will change this so that an error does
appear in dev mode. This migration fixes the configs by removing the
`canActivate` property.
PR Close#40067
Redirects in the router are processed before activations. This means that a canActivate will
never execute if a route has a redirect. Rather than silently ignoring
the invalid config, developers should be notified so they know why it
doesn't work.
Closes#18605
The feature request for a function/class redirect is covered in #13373.
PR Close#40067
Given the template
`<div (click)="doSomething($event)"></div>`
If you request references for the `$event`, the results include both `$event` and `(click)="doSomething($event)"`.
This happens because in the TCB, `$event` is passed to the `subscribe`/`addEventListener`
function as an argument. So when we ask typescript to give us the references, we
get the result from the usage in the subscribe body as well as the one passed in as an argument.
This commit adds an identifier to the `$event` parameter in the TCB so
that the result returned from `getReferencesAtPosition` can be
identified and filtered out.
fixes#40157
PR Close#40158
According to the [spec](https://html.spec.whatwg.org/#scroll-to-fragid),
we should attempt to set the browser focus after scrolling to a
fragment. Note that this change does not exactly follow the robust steps
outlined in the spec by finding a fallback target if the original is not
focusable. Instead, we simply attempt to focus the element by calling
`focus` on it, which will do nothing if the element is not focusable.
fixes#30067
PR Close#40241
The `ɵɵngDeclareDirective` calls are designed to be translated to fully
AOT compiled code during a build transform, but in cases this is not
done it is still possible to compile the declaration object in the
browser using the JIT compiler. This commit adds a runtime
implementation of `ɵɵngDeclareDirective` which invokes the JIT compiler
using the declaration object, such that a compiled directive definition
is made available to the Ivy runtime.
PR Close#40101
The linker is implemented using a Babel transform such that Babel needs
to parse and walk a source file to find the declarations that need to be
compiled. If it can be determined that a source file is known not to
contain any declarations the parsing and walking can be skipped as a
performance improvement. This commit adds an exposed function for tools
that integrate the linker to use to allow short-circuiting of the linker
transform.
PR Close#40137
Internally we store lifecycle hooks in the format `[index, hook, index, hook]` and when
iterating over them, we check one place ahead to figure out whether we've hit found
a hook or an index. The problem is that the loop is set up to iterate up to `hooks.length`
which means that we may go out of bounds on the last iteration, depending on where
we started. This appears to happen under a specific set of circumstances where a
directive calls `detectChanges` from an input setter while it has `ngOnChanges` and
`ngAfterViewInit` hooks.
These changes resolve the issue by only iterating up to `length - 1` which guarantees that
we can always look one place ahead.
This appears to have regressed some time in version 10.
Fixes#38611.
PR Close#40206
Previously `\r\n` was being treated as a single character in source-map
line start positions, which caused segment positions to become offset.
Now the `\r` is ignored when splitting, leaving it at the end of the
previous line, which solves the offsetting problem, and does not affect
source-mappings.
Fixes#40169Fixes#39654
PR Close#40187
This commit fixes an issue in the ivy native language service
that caused the logic that finds a target node given a template
position to throw away the results. This happened because the
source span of a variable node in the shorthand structural
directive syntax (i.e. `*ngIf=`) included the entire binding.
The result was that we would add the variable node to the path and then
later detect that the cursor was outside the key and value spans and
throw away the whole result. In general, we do this because we do not
want to show information when the cursor is between a key/value
(`inputA=¦"123"`). However, when using the shorthand syntax, we run into
the situation where we can match an `AttributeBinding` as well as the
vaariable in `*ngIf="som¦eValue as myLocalVar"`. This commit updates the
visitor to retain enough information in the visit path to throw away
invalid targets but keep valid ones if there were multiple results on a
`t.Element` or `t.Template`.
PR Close#40239
The linker entry-points were not previously exposed in the NPM Bazel
target so they were omitted from the bundle. This commit adds the
necessary entry-points to the compiler-cli's npm_package target.
PR Close#40180
The types of directives and pipes that are used in a component's
template may be emitted into the partial declaration wrapped inside a
closure, which is needed when the type is declared later in the module.
This poses a problem for JIT compilation of partial declarations, as
this closure is indistinguishable from a class reference itself. To mark
the forward reference function as such, this commit changes the partial
declaration codegen to emit a `forwardRef` invocation wrapped around
the closure, which ensures that the closure is properly tagged as a
forward reference. This allows the forward reference to be treated as
such during JIT compilation.
PR Close#40117
PR #39876 introduced an error where the `onDestroy` of `ComponentRef`
would only get called if `ngDevMode` was set to true. This was because
in dev mode we would freeze `TCleanup` to verify that no more
static cleanup would get added to `TCleanup` array. This ensured
that `TCleanup` was always present in dev mode. In production the
`TCleanup` would get created only when needed. The resulting cleanup
code was incorrectly indented and would only run if `TCleanup` was
present causing this issue.
Fix#40105
PR Close#40120
Escape the content of the strings so that it can be safely inserted into a comment node.
The issue is that HTML does not specify any way to escape comment end text inside the comment.
`<!-- The way you close a comment is with "-->". -->`. Above the `"-->"` is meant to be text
not an end to the comment. This can be created programmatically through DOM APIs.
```
div.innerHTML = div.innerHTML
```
One would expect that the above code would be safe to do, but it turns out that because comment
text is not escaped, the comment may contain text which will prematurely close the comment
opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
may contain such text and expect them to be safe.)
This function escapes the comment text by looking for the closing char sequence `-->` and replace
it with `-_-_>` where the `_` is a zero width space `\u200B`. The result is that if a comment
contains `-->` text it will render normally but it will not cause the HTML parser to close the
comment.
PR Close#40136
Currently when `ɵɵtemplate` and `ɵɵelement` instructions are generated by compiler, all static attributes are
duplicated for both instructions. As a part of this duplication, i18n translation blocks for static i18n attributes
are generated twice as well, causing duplicate entries in extracted translation files (when Ivy extraction mechanisms
are used). This commit fixes this issue by introducing a cache for i18n translation blocks (for static attributes
only).
Also this commit further aligns `ɵɵtemplate` and `ɵɵelement` instruction attributes, which should help implement
more effective attributes deduplication logic.
Closes#39942.
PR Close#40077
Durring analysis we find template parse errors. This commit changes
where the type checking context stores the parse errors. Previously, we
stored them on the AnalysisOutput this commit changes the errors to be
stored on the TemplateData (which is a property on the shim). That way,
the template parse errors can be grouped by template.
Previously, if a template had a parse error, we poisoned the module and
would not procede to find typecheck errors. This change does not poison
modules whose template have typecheck errors, so that ngtsc can emit
typecheck errors for templates with parse errors.
Additionally, all template diagnostics are produced in the same place.
This allows requesting just the template template diagnostics or just
other types of errors.
PR Close#40026
Refactors the i18n error tests to be unit tests in ngtsc_spec.ts. There
is two reasons for doing this.
First is that the tests in compliace_old expected an expection to be be
thrown but did not fail the test if no exception was thrown. That means
that this test could miss catching a bug. It is also a big hacky to call
compile directly and expect an exception to be thrown for diagnostics.
Also, this can easily be unit tested and an end-to-end test is not
necessary since we are not making use of the goldfiles for these tests.
It is easier to maintain and less hacky to validate that we get helpful
error messages when nesting i18n sections by calling getDiagnostics
directly.
PR Close#40026
This commit temporarily excludes classes declared in .d.ts files from checks
regarding whether providers are actually injectable.
Such classes used to be ignored (on accident) because the
`TypeScriptReflectionHost.getConstructorParameters()` method did not return
constructor parameters from d.ts files, mostly as an oversight. This was
recently fixed, but caused more providers to be exposed to this check, which
created a breakage in g3.
This commit temporarily fixes the breakage by continuing to exclude such
providers from the check, until g3 can be patched.
PR Close#40118
This comit adds support for autocompletion of attributes that create
structural directives. Such completions differ from those of normal
attributes, as the structural directive syntax creates a synthetic
<ng-template> node which has different attributes from the main element.
PR Close#40032
This commit introduces an `isStructural` flag on directive metadata, which
is `true` if the directive injects `TemplateRef` (and thus is at least
theoretically usable as a structural directive). The flag is not used for
anything currently, but will be utilized by the Language Service to offer
better autocompletion results for structural directives.
PR Close#40032
This commit adds attribute completion to the Language Service. It completes
from 3 sources:
1. inputs/outputs of directives currently present on the element
2. inputs/outputs/attributes of directives in scope for the element, that
would become present if the input/output/attribute was added
3. DOM properties and attributes
We distinguish between completion of a property binding (`[foo|]`) and a
completion in an attribute context (`foo|`). For the latter, bindings to
the attribute are offered, as well as a property binding which adds the
square bracket notation.
To determine hypothetical matches (directives which would become present if
a binding is added), directives in scope are scanned and matched against a
hypothetical version of the element which has the attribute.
PR Close#40032
This commit adds two new APIs to the `TemplateTypeChecker`:
`getPotentialDomBindings` and `getDirectiveMetadata`. Together, these will
support the Language Service in performing autocompletion of directive
inputs/outputs.
PR Close#40032
The `annotations` package in the compiler previously contained a registry
which tracks NgModule scopes for template type-checking, including unifying
all type-checking metadata across class inheritance lines.
This commit generalizes this utility and prepares it for use in the
`TemplateTypeChecker` as well, to back APIs used by the language service.
PR Close#40032
This commit expands the autocompletion capabilities of the language service
to include element tag names. It presents both DOM elements from the Angular
DOM schema as well as any components (or directives with element selectors)
that are in scope within the template as options for completion.
PR Close#40032
This commit extends the template targeting system, which determines the node
being referenced given a template position, to return additional context if
needed about the particular aspect of the node to which the position refers.
For example, a position pointing to an element node may be pointing either
to its tag name or to somewhere in the node body. This is the difference
between `<div|>` and `<div foo | bar>`.
PR Close#40032
The vim editor produces temporarily files that can end in both .swo and
.swp. This commits add .swp to the .gitignore so we don't accidentaly
commit temporary files.
PR Close#40094
This commit replaces `bazel` with `yarn bazel` in the error message (that instructs to regenerate golden file)
thrown while executing compliance tests. We use `yarn bazel` in other places (so we use the local version of bazel,
not the global one).
PR Close#40078