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